Io 我应该如何处理可以';不能逐行阅读()?
我正在玩Io 我应该如何处理可以';不能逐行阅读()?,io,raku,Io,Raku,我正在玩行,它从您在命令行上指定的文件中读取行: for lines() { put $_ } 如果它不能读取它抛出的一个文件名X::AdHoc(也许有一天它会有更好的异常类型,这样我们就可以用.path方法获取文件名)。很好,所以请注意: try { CATCH { default { put .^name } } for lines() { put $_ } } 这捕获了X::AdHoc错误,但仅此而已。此时将完成try块。无法。请继续,然后尝试下一个文件: try { CATCH {
行
,它从您在命令行上指定的文件中读取行:
for lines() { put $_ }
如果它不能读取它抛出的一个文件名X::AdHoc
(也许有一天它会有更好的异常类型,这样我们就可以用.path
方法获取文件名)。很好,所以请注意:
try {
CATCH { default { put .^name } }
for lines() { put $_ }
}
这捕获了X::AdHoc
错误,但仅此而已。此时将完成try
块。无法。请继续,然后尝试下一个文件:
try {
CATCH { default { put .^name; .resume } } # Nope
for lines() { put $_ }
}
回到Perl5Land,您会收到一条关于错误文件名的警告,程序将继续进行下一步
如果存在一些参数,我可以先过滤@*ARGS
,然后重建$*ARGFILES
:
$*ARGFILES = IO::CatHandle.new:
@*ARGS.grep( { $^a.IO.e and $^a.IO.r } ) if +@*ARGS;
for lines() { put $_ }
my $code := { put $_ };
@*ARGS = '-' unless +@*ARGS;
for @*ARGS -> $arg {
given $arg {
when '-' { $code.($_) for $*IN.lines(); next }
when ! .IO.e { note "$_ does not exist"; next }
when ! .IO.r { note "$_ is not readable"; next }
default { $code.($_) for $arg.IO.lines() }
}
}
尽管它会默默地忽略坏文件,但仍然有效。我可以处理这个问题,但自己处理参数列表有点繁琐,包括标准输入的-
文件名和默认值(不带参数):
$*ARGFILES = IO::CatHandle.new:
@*ARGS.grep( { $^a.IO.e and $^a.IO.r } ) if +@*ARGS;
for lines() { put $_ }
my $code := { put $_ };
@*ARGS = '-' unless +@*ARGS;
for @*ARGS -> $arg {
given $arg {
when '-' { $code.($_) for $*IN.lines(); next }
when ! .IO.e { note "$_ does not exist"; next }
when ! .IO.r { note "$_ is not readable"; next }
default { $code.($_) for $arg.IO.lines() }
}
}
但这需要做很多工作。是否有更简单的方法来处理此问题?若要在错误打开时发出警告并继续,可以使用以下方法:
$*ARGFILES does role { method next-handle { loop {
try return self.IO::CatHandle::next-handle;
warn "WARNING: $!.message"
}}}
.say for lines
简单地说,这会使方法重新尝试获取下一个句柄。(您也可以使用混入副本)
如果它不能读取它抛出的一个文件名X::AdHoc
X::AdHoc
来自.open
调用;有一个异常,所以一旦修复了它,IO::CatHandle
也会抛出类型化异常
不行,继续
是的,您只能从捕获它的CATCH
块恢复,但在这种情况下,它在内被捕获。打开调用,并进入失败,然后由IO::CatHandle接收。下一个句柄及其.exception
是re-.throw
n
然而,即使它在这里是可恢复的,它也只是恢复到引发异常的路径中,而不是使用另一个句柄重试。这没用。(我考虑过使其可恢复,但这给开关上的增加了模糊性,我不愿意指定从某些位置恢复异常必须能够有意义地继续,我们目前不为核心中的任何位置提供这样的保证)
包括标准输入的-
作为文件名
请注意,这一特殊含义仅限于IO::Handle.open
(扩展为IO::CatHandle.new
)。它可能会在IO::ArgFiles
中得到特殊处理,但我还没有看到这样的建议
回到Perl5Land,您会收到一条关于错误文件名的警告,程序将继续进行下一步
在Perl 6中,它被实现为一种通用的IO::CatHandle
类型,用户可以用它来做任何事情,而不仅仅是文件参数,因此,在默认情况下,警告和继续前进对我来说太过宽松了
IO::ArgFiles
可以是提供这种行为的特殊情况。就我个人而言,我反对到处都是特殊外壳的东西,我认为这是Perl 5中最大的缺陷,但是你可以看看是否有人支持它。我认为这里的错误实际上是一个错误。它不是带有a.path
和b的类型化异常。它是不可恢复的。请为此创建GH issue/RT票证。@ElizabethMattijsen FWIW:查看规范,我们不保证。恢复核心抛出异常的能力;更不用说保证了。恢复将产生任何有意义的行为(例如使用下一个句柄重试)。在国际海事组织,我们不应该只是一时兴起就开始支持它,而应该看看是否可以作为一种通用模式支持整个核心。(FWIW使IO::CatHandle.next-handle直接抛出X::AdHoc,并在某个次要位置用“发生了错误(AdHoc)”,恢复后爆炸)我认为它应该作为序列的一部分给出,而不是抛出错误。如果错误出现在Seq中,那么它可以像调用next
一样简单。@BradGilbert从行调用Seq
?这将破坏(只读)IO::Handle和IO::CatHandle的可互换性,并且对其他方法没有帮助,例如.read
或.slurp
。在成功从“文件”中读取后,让它抛出“未找到文件”错误也会破坏可互换性。按照现在的工作方式,在用户代码中重新实现算法似乎比使用内置算法更容易;可能会导致新的Perl 6程序员编写了许多糟糕的重新实现。现在,您基本上必须知道如何实现它来解决它。有很多方法是不可互换的,比如试着写下来。我们的目标应该是有效地互换。(可能有比我提议的更好的办法,我接受)@BradGilbert我根本不明白你提议解决什么问题。该提案仅仅为用户创造了令人惊讶的行为,创建了隐藏(例如,my@lines=lines
现在有未经证实的故障),增加了检查每一行错误的开销,并且对所有其他读取方法都没有解决任何问题。如果它以内联方式返回它们,您至少可以执行.grep(&defined)
如果你不在乎失败。如果你真的在乎失败,但你希望能够继续;目前,你还不能完全做到这一点。