在Perl中,人们经常可以避免使用控制块,如下所示:
print "$_\n" foreach(@files);
而不是:
foreach(@files){
print "$_\n";
}
此语法如何在以下更复杂的情况下起作用:
die("Not a file: $_") unless -f $_ foreach(@files);
它给我一个语法错误。我不是要编写混淆代码,它只是程序中不重要的部分,所以我想尽可能简洁地表达它。
概述答案:
我只接受一个答案作为接受的答案,但我最喜欢克里斯和乔恩的以下答案。
这个按照我的意图使用foreach
,但不使用syntax error
:
-f or die "Not a file: $_" foreach @files;
以下一个至少同样好。我喜欢die
在声明的开头,因为这是读者应该注意的:
die("Not a file: $_") for grep {!-f} @files;
答案 0 :(得分:13)
只需要Perlish(TMTOWTDI)就可以使用逻辑短路:
-f or die "Not a file: $_" foreach @files;
在OS X上测试并正常工作。
作为旁注,-f or die
看起来像我在Perl中看到的许多常见open() or die
构造,但仍然(我认为)显示了该行的意图(在某些条件下到die
。
答案 1 :(得分:11)
您可以使用@ Brent.Longborough的答案,或者如果您真的想要postfix,请执行:
do { die("Not a file: $_") unless -f $_ } foreach(@files);
然而,我同意其他人,只是因为这是“一个不重要的部分”并不意味着简洁更好。 可读性很重要。
答案 2 :(得分:7)
好吧,你可能不是打算来编写混淆代码,但我会说你肯定尝试。
两条线(或者甚至是一条线上的一块,就像Brent.Longborough所暗示的那样)而不是一条线那么糟糕?老实说,这就是我一般不喜欢尝试调试/编辑其他人的perl代码的原因,大量用perl编写的人似乎都沉迷于以最“聪明”的方式做几乎所有事情,而不是去做用其他人阅读的方式很容易理解。
答案 3 :(得分:5)
如果错误测试是此代码的主要部分,那么将它放在行的开头可能是有意义的。稍微改进就是使用grep
:
die("Not a file: $_") for grep {!-f} @files;
但是如果你计划在代码的那一部分中出于某些其他原因循环遍历文件,那么最好将它添加到循环体中。
答案 4 :(得分:3)
如果您没有尝试编写混淆代码,那么您不应该尝试这样写。你正在采取一些应该简单并且难以理解的东西。
答案 5 :(得分:1)
你的想法太难了。这是一行没有杂技:
foreach ( @files ) { die( "Not a file!" ) unless -f }
你可以玩一下这个区域内的东西来打高尔夫球,但是移除那些parens和大括号并没有帮助你,并且可能会让下一个必须看它的程序员感到困惑。
你可能有更复杂的东西,这只是一个例子。在现实世界中,它变得更加容易:
not_a_file_die_die_die( \@files );
然后将所有复杂的东西移动到子程序中。真正的诀窍是使想法和 intent 简洁,而不是实现这个想法的代码。在许多情况下,机制确实无关紧要;你更关心结果。在这些情况下,不要让机械师大汗淋漓。
答案 6 :(得分:0)
该死的,乔恩只是打败了我grep
。
但是我有一个更大的问题:如果你在阵列中找到一些非文件,你实际上要拯救它是多么重要? (而不是说,删除这些项目,警告用户,然后处理列表的其余部分。)我认为杀死整个shebang是该计划的一个相当重要的部分。
在任何情况下,你都不能用postfix修饰符做你想要的,因为你只能在它们的两边都有一个东西。因此,您不能同时拥有unless
和foreach
。从perldoc perlsyn
的相关位顶部开始:
任何简单的语句都可以选择后跟一个 SINGLE 修饰符,就在终止分号(或块结尾)之前。