如汤姆·布劳德(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
将无效的文件句柄用于任何内容时,就会发生此问题。有没有办法在引起异常之前检查文件句柄是否有效?
答案 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
(延迟任何异常抛出),而是立即抛出一个异常(也许只有这样一个异常才能起作用)只是延迟或出现故障)。
这似乎是错误的或非常错误的。
请参见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()?
也:
https://github.com/rakudo/rakudo/search?q=argfiles&type=Issues
https://github.com/rakudo/rakudo/search?q=cathandle&type=Issues
在讨论"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
的类)或起任何作用。
因此,$*ARGFILES
是IO::CatHandle
对象(在功能上完全相同),它是IO::Handle
对象(功能的超集),具体来说:
IO::CatHandle
类提供一种创建IO::Handle
的方法,该方法无缝地收集来自多个IO::Handle
和IO::Pipe
的输入。IO::Handle
的所有方法均已实现,尽管尝试使用write方法(当前)会引发异常,但在可以使用只读IO::CatHandle
的任何地方都可以使用IO::Handle
。
IO::CatHandle
(要在以后填写吗?)