处理无效的文件句柄(也许还有其他无效的对象)

时间:2019-02-03 09:28:39

标签: exception-handling io perl6

如汤姆·布劳德(Tom Browder)在this issue中指出的那样,如果不存在命令行中提到的任何文件,则$*ARGFILES dynamic variable可能包含无效的文件句柄。

for $*ARGFILES.handles -> $fh {
    say $fh;
}

将失败,并出现X::AdHoc异常(这也可能会得到改善):

Failed to open file /home/jmerelo/Code/perl6/my-perl6-examples/args/no-file: No such file or directory

将无效的文件句柄用于任何内容时,就会发生此问题。有没有办法在引起异常之前检查文件句柄是否有效?

2 个答案:

答案 0 :(得分:8)

您可以通过是否检查是否真实性或定义性来检查某物是否为Failure

Failure

如果您仍然想扔掉for $*ARGFILES.handles -> $fh { say $fh if $fh; # check truthiness .say with $fh; # check definedness + topicalization } 所包含的Exception,则只需Failure

答案 1 :(得分:3)

TL; DR 我以为Liz已将其钉牢,但似乎有一个错误或也许是Ugh。

一个错误?

似乎IO::CatHandle class's .handles method到达权利应处理的句柄时,会产生Failure(延迟任何异常抛出),而是立即抛出一个异常(也许只有这样一个异常才能起作用)只是延迟或出现故障)。

这似乎是错误的或非常错误的。

gh

请参见the exchange between Zoffix and Brad Gilbert and Zoffix's answer的问题How should I handle Perl 6 $*ARGFILES that can't be read by lines()?

也:

当前可能的解决方法是另一个错误?

在讨论"Implement handler for failed open on IO::CatHandle"时,Zoffix ++将此代码作为解决方案将其关闭:

.say for ($*ARGFILES but role {
    method next-handle {
        loop {try return self.IO::CatHandle::next-handle}
    }
})

我看到tbrowder重新打开了此问题,作为该SO即将说的相关问题的一部分:

  

如果这行得通,那么至少是文档中$*ARGFILES变量的可用示例。

但是,当我在6.d中运行它(并且看到6.c的结果类似)时,无论有没有有效的输入,我都会得到:

say not yet implemented

(如果我是.put或其他人,则与此类似。

这太疯狂了,这表明有些固执己见。

我已经在rt和gh / rakudo问题中搜索了“尚未实施”,没有找到匹配项。

另一个解决方法?

Zoffix明确希望将其代码用作永久解决方案,而不仅仅是解决方法。不幸的是,它似乎暂时还无法正常工作。

到目前为止,我想出的最好的方法:

try {$*ARGFILES} andthen say $_    # $_ is a defined ArgFiles instance
                 orelse  say $!;   # $! is an error encountered inside the `try`

也许这是黑白的,要么全部起作用,要么都不起作用。 (尽管我不敢相信甚至如此。)

文档对$*ARGFILES的评价

$*ARGFILES说它是

的一个实例

IO::ArgFiles,它被记录为一个类,

  

出于向后兼容的原因而存在,并且不提供任何方法。

  

所有功能都继承自

IO::CatHandle,副标题为

  

使用多个IO句柄,就像它们是一个

并记录为is

的类

IO::Handle,副标题为

  

打开的文件或流

并且将其文档化为不继承自任何其他类的类(因此默认为继承自Any的类)或起任何作用。

因此,$*ARGFILESIO::CatHandle对象(在功能上完全相同),它是IO::Handle对象(功能的超集),具体来说:

  

IO::CatHandle类提供一种创建IO::Handle的方法,该方法无缝地收集来自多个IO::HandleIO::Pipe的输入。 IO::Handle的所有方法均已实现,尽管尝试使用write方法(当前)会引发异常,但在可以使用只读IO::CatHandle的任何地方都可以使用IO::Handle

浏览the code for IO::CatHandle

(要在以后填写吗?)