Chen Yangjian's Blog

Carpe diem - Seize the day

Perl: See Brainfuck

| Comments

前些天,有好事者号召大家说说什么编程语言最适合做什么:let’s see what languages are best for what.(很不错,推荐一看)

不幸的是 Perl 的评论是这样的:

Perl - see brainfuck

Perl - when you need something to start working ASAP and don’t want any lip from the compiler. …and want a slew of silent runtime bugs instead.

时隔多日,今天老大突然又让我解析一些存储过程(Stored Procedure),不过都是些轻活,不需要解析 SQL,只要把文件头的注释和某几句话去去掉,就是了。麻烦的是需要把原先的文件划分重新搞,按 schema 归类。自然就像用散列来做,弄个类似

('schema_one' => ('sp1', 'sp2'), 'schema_two' => ('sp3', 'sp4'))

的结构。这才发现 Perl 的散列的值只能是 scalar。介绍到 a hash of lists 的 perldoc 自己也笑了:

One of the most important new features in Perl 5 was the capability to manage complicated data structures like multidimensional arrays and nested hashes. To enable these, Perl 5 introduced a feature called `references’, and using references is the key to managing complicated, structured data in Perl. Unfortunately, there’s a lot of funny syntax to learn, and the main manual page can be hard to follow.

Perl 的语法确实太乱了…… 括号可以省略;条件语句可以倒置;continue 叫做 next;else if 不好好写,写成 elsif;还有两个万恶的变量叫做 $ 和 @;string 的比较(eq, ne, lt, …)跟整形的比较操作符(==, !=, <, …)居然是不一样的,如果不小心用了,连个错误信息都没有;最离谱的是,函数的参数与返回值是不需要显式说明的(当然,这不确切,准确说是,参数是需要写到函数体当中,而返回值则是函数体最后一句的返回值,如果不幸那一句没有返回值,那就得显式得在末尾写上变量。折腾来折腾去,省了一个 return)。

用不着这么标新立异吧?

再说回到如何在 perl 里头实现复杂数据结构。一般情况下,知道如何取地址(\%, \@, \$)和根据地址取值(%{}, @{}, ${})也就够了。如下:

$aref = \@array; # $aref now holds a reference to @array
@list = @{$aref}; # @array now restores the value of @array.

Larry Wall 觉得这样不够好玩,同时他还觉得 [] 和 {} 不能只用来做索引操作符(定义数组和散列时,默认用得是括号),-> 操作符他也没有用上。于是就有了这样的代码:

$aref = [1, 2, 3];
print $aref->[2]; # 3

头大了没有?

Comments