我应该如何处理行()无法读取的Perl 6 $ * ARGFILES? [英] How should I handle Perl 6 $*ARGFILES that can't be read by lines()?

查看:113
本文介绍了我应该如何处理行()无法读取的Perl 6 $ * ARGFILES?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在玩,它会从您在命令行中指定的文件中读取行:

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-.thrown.

然而,即使它在这里可以恢复,它也会简单地恢复到抛出异常的路径,而不是用另一个句柄重新尝试。这没有用。 (我调查了它可以恢复,但这增加了 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 Exceptions 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆