无效的文件句柄(也许其他无效对象太)为IO的处理代码:: CatHandle

问题描述 投票:7回答:2

正如汤姆·布劳德在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

作为无效文件句柄被用于任何会尽快出现问题。会有检查,如果该文件句柄处于异常引起之前有效的方法是什么?

exception-handling io perl6
2个回答
3
投票

TL; DR我认为利兹有它钉但似乎有一个bug或者是唉。

A bug?

它看起来像每当IO::CatHandle class's .handles method达到,本应通过权利产生Failure(延迟任何异常抛出),而是立即抛出一个异常(可能是一个非常,如果它只是推迟或可能打破东西,将工作)的句柄。

这看起来或者是错误的或者非常错误的。

Ugh

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()?

也:

A potential workaround is currently another bug?

在讨论"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 VAR可用的例子。

但是,当我在6.d运行它(并看到了6.c类似的结果),有或无有效输入时,我得到:

say not yet implemented

(类似的,如果我.put或其他)。

这是坚果和建议勇敢的事是越来越混乱。

我搜索RT和GH / rakudo问题为“尚未实现”,看看有没相关的匹配。

Another workaround?

Zoffix显然是他们的代码作为一个永久性的解决方案,而不仅仅是一个解决方法。但不幸的是它似乎并没有在所有的工作现在。

我想出了迄今为止最好的:

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

也许这可以作为一个非黑即白,要么所有的作品或没有它的解决方案。 (虽然我不相信它甚至这一点。)

What the doc has to say about $*ARGFILES

$*ARGFILES说,这是一个实例

IO::ArgFiles其doc'd作为一类,其

存在对向后兼容的原因,并且不提供方法。

所有的功能是继承自

IO::CatHandle副标题是作为

使用多个IO处理,就好像它们是一个

和doc'd作为is

IO::Handle副标题是作为

打开文件或流

和doc'd为不从其它类继承一个类(所以默认为从Any继承)或做任何作用。

所以,$*ARGFILES是(恰好功能上相同)一个IO::CatHandle对象,它是一个对象IO::Handle,具体地(的的功能的超集):

所述IO::CatHandle类提供创建来自多个IO::HandleIO::Handle源无缝集输入一个IO::Pipe的装置。所有的IO::Handle的方法来实现,同时尝试使用写入方法将(目前)抛出一个异常,一个IO::CatHandle可用任何地方只读IO::Handle可以使用。

Exploring the code for IO::CatHandle

(稍后填写?)


8
投票

您可以检查,如果事情是Failure通过检查感实性或definedness没有Failure投掷:

for $*ARGFILES.handles -> $fh {
    say $fh if $fh;  # check truthiness
    .say with $fh;   # check definedness + topicalization
}

如果你仍然想扔了Exception涵盖Failure,那么你可以只.throw它。

© www.soinside.com 2019 - 2024. All rights reserved.