我应该如何处理行()无法读取的Perl 6 $ * ARGFILES? [英] How should I handle Perl 6 $*ARGFILES that can't be read by lines()?
问题描述
我正在玩行
,它会从您在命令行中指定的文件中读取行:
I'm playing around with lines
which reads lines from the files you specify on the command line:
for lines() { put $_ }
如果是无法读取它抛出的其中一个文件名 X :: AdHoc
(有一天它可能有更好的异常类型,所以我们可以用 .path
方法)。很好,所以赶上:
If it can't read one of the filenames it throws X::AdHoc
(one day maybe it will have better exception types so we can grab the filename with a .path
method). Fine, so catch that:
try {
CATCH { default { put .^name } }
for lines() { put $_ }
}
所以这就抓住了 X :: AdHoc
错误,但就是这样。此时尝试
块已完成。它不能 .resume
并尝试下一个文件:
So this catches the X::AdHoc
error but that's it. The try
block is done at that point. It can't .resume
and try the next file:
try {
CATCH { default { put .^name; .resume } } # Nope
for lines() { put $_ }
}
回到Perl 5的土地,你会收到关于文件名错误的警告,然后程序转到下一个文件。
Back in Perl 5 land you get a warning about the bad filename and the program moves on to the next thing.
我可以过滤 @ * ARGS
首先重建 $ * ARGFILES
如果有一些参数:
I could filter @*ARGS
first then reconstruct $*ARGFILES
if there are some arguments:
$*ARGFILES = IO::CatHandle.new:
@*ARGS.grep( { $^a.IO.e and $^a.IO.r } ) if +@*ARGS;
for lines() { put $_ }
虽然有效默默地忽略坏文件。我可以处理这个但是我自己处理参数列表有点乏味,包括 -
标准输入作为文件名,默认情况下没有参数:
That works although it silently ignores bad files. I could handle that but it's a bit tedious to handle the argument list myself, including -
for standard input as a filename and the default with no arguments:
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() }
}
}
但这是很多工作。有没有更简单的方法来处理这个?
But that's a lot of work. Is there a simpler way to handle this?
推荐答案
要警告糟糕的打开并继续前进,你可以使用这样的东西:
To warn on bad open and move on, you could use something like this:
$*ARGFILES does role { method next-handle { loop {
try return self.IO::CatHandle::next-handle;
warn "WARNING: $!.message"
}}}
.say for lines
只需混合角色即可使 IO :: CatHandle.next-handle 方法重试下一个句柄。 (您也可以使用 但
运营商来反而在混合中使用)。
Simply mixing in a role that makes the IO::CatHandle.next-handle method re-try getting next handle. (you can also use but
operator to mixin on a copy instead).
如果它无法读取其中一个文件名抛出X :: AdHoc
If it can't read one of the filenames it throws X::AdHoc
X :: AdHoc
来自 .open
call;有一个有点发霉的PR可以输入这些例外,所以一旦修复, IO :: CatHandle
也会抛出类型异常。
The X::AdHoc
is from .open
call; there's a somewhat moldy PR to make those exceptions typed, so once that's fixed, IO::CatHandle
would throw typed exceptions as well.
它不能.resume
It can't .resume
是的,你只能从捕获它的 CATCH
块中恢复,但是在这种情况下,它被捕获到 .open
调用并被转换为失败
,然后由<$ c接收$ c> IO :: CatHandle.next-handle 及其 .exception
重新< - code> .throw n。
Yeah, you can only resume from a CATCH
block that caught it, but in this case it's caught inside .open
call and is made into a Failure
, which is then received by IO::CatHandle.next-handle
and its .exception
is re-.throw
n.
然而,即使它在这里可以恢复,它也会简单地恢复到抛出异常的路径,而不是用另一个句柄重新尝试。这没有用。 (我调查了它可以恢复,但这增加了 on-switch
的模糊性,我不习惯指出恢复异常
来自某些地方必须能够有意义地继续 - 我们目前不为核心地点提供这样的保证。)
However, even if it were resumable here, it'd simply resume into a path where exception was thrown, not re-try with another handle. It wouldn't help. (I looked into making it resumable, but that adds vagueness to on-switch
and I'm not comfortable speccing that resuming Exception
s from certain places must be able to meaningfully continue—we currently don't offer such a guarantee for any place in core).
包括
-
标准输入作为文件名
请注意那个特殊含义是离开在6.d语言至 IO :: Handle.open
(以及扩展名 IO :: CatHandle.new
)去了。它可能会在 IO :: ArgFiles
中得到特殊处理,但我没有看到提议。
Note that that special meaning is going away in 6.d language as far as IO::Handle.open
(and by extension IO::CatHandle.new
) goes. It might get special treatment in IO::ArgFiles
, but I've not seen that proposed.
回到Perl 5之后,你会收到关于文件名错误的警告,然后程序转到下一步。
Back in Perl 5 land you get a warning about the bad filename and the program moves on to the next thing.
在Perl 6中,它实现为通用的 IO :: CatHandle
类型,用户可以用于任何事情,而不仅仅是文件参数,默认情况下警告和继续对我来说太麻烦了。
In Perl 6, it's implemented as a generalized IO::CatHandle
type users can use for anything, not just file arguments, so warning and moving on by default feels too lax to me.
IO :: ArgFiles
可能是特殊的提供这样的行为。就个人而言,我反对整个地方的特殊外壳,我认为这是Perl 5中最大的缺陷,但你可以打开一个提议的问题并查看是否有人支持它。
IO::ArgFiles
could be special-cased to offer such behaviour. Personally, I'm against special casing stuff all over the place and I think that is the biggest flaw in Perl 5, but you could open an Issue proposing that and see if anyone backs it.
这篇关于我应该如何处理行()无法读取的Perl 6 $ * ARGFILES?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!