Perl 的一些优雅特性或用途是什么?

36

"什么?Perl漂亮?优雅?他一定是在开玩笑!"

事实是,有些Perl代码确实很丑陋。我指的是很多。我们都见过。

"当然了,它就是一个符号汤。不是吗?"

是的,有符号。就像“数学”有“符号”一样。只是我们程序员更熟悉标准的数学符号。我们接受来自母语的符号,无论是ASM、C还是Pascal。Perl只是决定要多一些。

"好吧,我认为我们应该摆脱所有不必要的符号。这样代码看起来更好看。"

已经存在用于这样做的语言。它叫做Lisp。(以及即将到来的perl 6。)

"好的,聪明的家伙。事实是,我已经可以发明自己的符号了。它们被称为函数和方法。此外,我们不想重新发明APL。"

哦,虚假的替身,你太有趣了!事实上,Perl可以非常美丽。它也可以非常丑陋。在Perl中,TIMTOWTDI

那么,你最喜欢的优雅的Perl代码是什么?


嗯... 标签混乱?Perl作为一种编程语言而非标记语言,不太会有标签。如果您指的是'man perlfunc'中的内容,那些是函数。 - chaos
也许这是一个操作符混合物... - Chris Lutz
4
在另一种语言中,这段代码将扩展为20行代码。 - 1800 INFORMATION
5
“非 ASCII 字符与 ASCII 字符之比”,上次我查看时,所有这些字符都是 ASCII 字符:{ } < > = $ _ @ -。 - AmbroseChapel
@ysth,坚持使用TMTOWTDI的规范拼写似乎与TMTOWTDI的精神背道而驰。 :-) (我敢肯定沃尔在一次State of the Onion中曾经提到过这一点,但我找不到了。) - LSpice
显示剩余7条评论
14个回答

2

除了 mapgrep 的使用外,我们还可以编写一个简单的命令行解析器。

my %opts = map { $_ => 1 } grep { /^-/ } @ARGV;

如果需要,我们可以将每个标志设置为其在@ARGV中的索引:
my %opts = map { $ARGV[$_] => $_ } grep { $ARGV[$_] =~ /^-/ } 0 .. $#ARGV;

那么,如果一个标记有一个参数,我们可以像这样获取参数:
if( defined( $opts{-e} ) ) {
  my $arg = $ARGV[ $opts{-e} ];
  # do -e stuff for $arg
}

当然,有些人可能会抱怨我们在重新发明轮子,建议使用 getopt 或其某个变体,但老实说,这是一个相当容易的轮子可以重新发明。而且,我不喜欢 getopt。
如果你不喜欢某些行有多长,你可以使用中间变量或方便的换行符(嘿,Python 狂热者?你听到了吗?我们可以将一行代码分成两行,它仍然可以工作!)使其看起来更好:
my %opts = map  { $ARGV[$_] => $_   }
           grep { $ARGV[$_] =~ /^-/ } 0 .. $#ARGV;

我尽可能使用map和grep(而不是foreach循环)。 我对它们的抱怨是它们没有命名$ _参数,如果代码需要引用多个级别的$ _,这是不好的。 - reinierpost

1

这个文件解析机制紧凑而且易于自定义(跳过空白行,跳过以 X 开头的行等等)。

open(H_CONFIG, "< $file_name") or die("Error opening file: $file_name! ($!)");
while (<H_CONFIG>)
{
   chomp;         # remove the trailing newline
   next if $_ =~ /^\s*$/; # skip lines that are blank
   next if $_ =~ /^\s*#/; # skip lines starting with comments
   # do something with the line
}

我在各种构建情况下使用这种结构 - 在那些需要预处理或后处理有效载荷文件(S-records等)或C文件,或者收集目录信息以进行“智能构建”的情况下。


1
我的最爱 Perl 的优雅之处在于它对数字值和字符串值使用不同的运算符。
my $string = 1 . 2;
my $number = "1" + "2";
my $unambiguous = 1 . "2";

与其他动态语言(如JavaScript)相比,JavaScript中使用“+”进行字符串连接和数学加法运算。
var string = "1" + "2";
var number = 1 + 2;
var ambiguous = 1 + "2";

或者是针对动态语言,如Python和Ruby,需要在字符串和数值之间进行类型转换。
string = "1" + "2"
number = 1 + 2
throws_exception = 1 + "2"

在我看来,Perl做得非常正确,而其他编程语言则做得很糟糕。

-17
像我这样打字速度较慢的人,经常按Shift键会手抽筋,而且几乎有一种无理的恐惧使用分号,所以我们开始在python格式的文件中编写Perl代码。 :)
例如:
>>> k = 5
>>> reduce(lambda i,j: i*j, range(1,k+1),1)
120
>>> k = 0
>>> reduce(lambda i,j: i*j, range(1,k+1),1)
1

1
使用 reduce { $a * $b } 1 .. $k, 1; 比你的 Python 示例少用了一个移位符号 ;-P - draegtun
3
我也讨厌按Shift键。这就是为什么我再也不会使用乘法了。想到解决方法,__rmult__需要按下4个下划线和在任何优雅的语言中输入'rmult'时都需要按下Shift键来输入parens(括号)--所以我放弃了编码。 - Axeman
@popcnt - 添加一个条件来检查0!是微不足道的,在Perl中使用if的后缀表示法根本不需要按Shift键(除了$varname)- 只需执行“return 0 if $var == 0;”,您就可以覆盖它,比以前多只需1个shift。 - Chris Lutz
@Chris Lutz:添加额外的检查有点使“优雅”失去了意义,不是吗?另外,0!== 1,所以这就是我喜欢指出它的棘手之处的原因。 - popcnt
@popcnt - 如果你是真诚的,那我很抱歉。只是你会看到足够多的这样的消息:“我如何在Perl中解决zeppelin的问题?”得到的回答是“使用Python”。如果需要消除移位操作,那么这是有意义的,但这似乎并不是关于“优雅的Perl”的普遍关注点。 - Axeman
显示剩余14条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接