6

在 Perl 中,通常可以避免使用控制块,如下所示:

print "$_\n" foreach(@files);

代替:

foreach(@files){
  print "$_\n";
}

此语法在以下更复杂的情况下如何工作:

die("Not a file: $_") unless -f $_ foreach(@files);

它给了我一个语法错误。我不是想写混淆代码,它只是程序中不重要的部分,所以我想尽可能简洁地表达它。

总结答案:

我只能接受一个答案作为已接受的答案,但我最喜欢 Chris 和 Jon 的以下答案。

这个foreach按我的意图使用,但没有syntax error

-f or die "Not a file: $_" foreach @files;

下面的一个至少也一样好。我喜欢die在声明的开头,因为这就是读者的注意力应该指向的内容:

die("Not a file: $_") for grep {!-f} @files;
4

7 回答 7

13

只是要成为 Perlish (TMTOWTDI),您可以使用逻辑短路:

-f or die "Not a file: $_" foreach @files;

在 OS X 上测试并且可以工作。

作为旁注,-f or die看起来像open() or die我在 Perl 中看到的许多常见结构,并且(认为)仍然显示了该行的意图(die在某些条件下)。

于 2009-02-20T18:01:21.847 回答
11

您可以使用@Brent.Longborough 的答案,或者如果您真的想要后缀,请执行以下操作:

do { die("Not a file: $_") unless -f $_ } foreach(@files);

但是,我同意其他人的观点,仅仅因为这是“不重要的部分”并不意味着简洁更好。 可读性很重要。

于 2009-02-20T16:52:08.330 回答
7

好吧,您可能不打算编写混淆代码,但我想说您肯定在尝试

两条线(或者甚至一条线上的一个街区,就像 Brent.Longborough 建议的那样)而不是一条线会那么糟糕吗?老实说,这就是我通常讨厌尝试调试/编辑其他人的 perl 代码的原因,大量使用 perl 编写的人似乎痴迷于以最“聪明”的方式做几乎所有事情,而不是这样做以一种其他人阅读时易于理解的方式。

于 2009-02-20T16:47:12.227 回答
5

如果错误测试是此代码的主要点,那么将主要位置放在行首可能是有意义的。一个轻微的改进是使用grep

die("Not a file: $_") for grep {!-f} @files;

但是,如果您计划在该部分代码中出于其他原因循环文件,最好将其添加到循环体中。

于 2009-02-20T17:47:52.347 回答
3

如果您不尝试编写混淆代码,那么您不应该尝试像这样编写它。你正在接受一些应该很简单的东西,却使它难以理解。

于 2009-02-20T16:48:33.300 回答
1

你想太多了。这是一条没有杂技的行:

 foreach ( @files ) { die( "Not a file!" ) unless -f }

您可能会玩弄块内的东西以将其击倒,但移除括号和大括号对您没有任何帮助,并且可能会使下一个必须查看它的程序员感到困惑。

你可能有更复杂的东西,这只是一个例子。在现实世界中,它变得更加容易:

not_a_file_die_die_die( \@files );

然后你将所有复杂的东西移到一个子程序中。真正的诀窍是使想法意图简洁,而不是实现想法的代码。在许多情况下,机制真的无关紧要。你更关心结果。在这些情况下,不要让机械师出汗。

于 2009-09-20T18:08:42.673 回答
0

该死的,乔恩刚刚打败了我grep

但我有一个更大的问题:如果您在阵列中发现一些非文件,您是否真的要退出,这有什么不重要的?(与删除这些项目、警告用户然后处理列表的其余部分相反。)我认为杀死整个 shebang 是程序中相当重要的部分。

在任何情况下,你都不能完全用后缀修饰符来做你想做的事,因为你只能在它们的两边都有一个东西。所以你不能同时拥有unlessforeach。从相关位的顶部开始perldoc perlsyn

任何简单的语句都可以选择后跟一个SINGLE修饰符,就在终止分号(或块结束)之前。

于 2009-02-20T17:53:37.713 回答