停止已久的《Perl Best Practices》翻译今天重新开始了。继续讲代码布局。


2.5 键和索引

复杂的键或者索引要与他们周围的括号分开。

访问嵌套数据(例如散列中散列其中再有数组)时,很容易产生相当长并且非常复杂的表达式, 极难阅读。例如:

$candidates[$i] = $incumbent{$candidates[$i]{get_region( )}};

像上面这样把所有内容都挤在一起很不容易看懂,也很难看出某个括号到底属于哪一层。

除非索引是简单的数据,否则都应该在索引和括号之间加入空格,以增强可读性:

$candidates[$i] = $incumbent{ $candidates[$i]{ get_region( ) } };

这里的决定因素不仅仅是复杂性,也包括表达式的整体长度。 如果索引的名字太长,那么即使它是一个单一的值,也最好加上空格。 例如:

print $incumbent{ $largest_gerrymandered_constituency };

这种写法明显要好于下面这种:

print $incumbent{$largest_gerrymandered_constituency};

2.6 运算符

用空格让二元运算符更醒目。

过长的表达式,若将各个部分都挤在一起,将非常读懂:

my $displacement=$initial_velocity*$time+0.5*$acceleration*$time**2;
my $price=$coupon_paid*$exp_rate+(($face_val+$coupon_val)*$exp_rate**2);

应当为二元运算符留出一点活动空间,即使这样会导致代码换行也是值得的:

my $displacement
    = $initial_velocity * $time  +  0.5 * $acceleration * $time**2;

my $price
    = $coupon_paid * $exp_rate  +  ($face_val + $coupon_paid) * $exp_rate**2;

另外,也可以根据运算符的优先顺序来调整空格的数量,例如低优先级的运算符两侧 添加更多的空格,以从视觉上将其与那些高优先级的运算符分开。而像 ** 这样的 高优先级运算符,则甚至可以两侧不加任何空格。

2.7 分号

每条语句之后都要写分号。

C程序员可能对这一条没什么话说。这一条是因为在perl中,分号是语句分隔符, 而不是语句结束符。因此,一个代码快的最后一行代码后是无须加分号的。例如下面的代码 是完全正确的:

while (my $line = <>) {
    chomp $line;

    if ( $line =~ s{\A (\s*) -- (.*)}{$1#$2}xms ) {
        push @comments, $2
    }

    print $line
}

但问题是,随着开发的进行,可能会需要在最后一行之前添加一些代码。 如果没有注意到前面的 print $line 没有分号,就有可能会变成这个样子:

    print $line
    $src_len += length;

更要命的是上面这段代码不会产生编译错误,因为Perl会把它们当成一条语句,相当于:

    print $line ($src_len += length);

因此,为避免这种错误的发生,还是老老实实地加上分号吧。 while (my $line = <>) { chomp $line;

    if ( $line =~ s{\A (\s*) -- (.*)}{$1#$2}xms ) {
        push @comments, $2;
    }

    print $line;
}

但有一种情况例外,那就是在使用grep或者map时,其内部的代码块最好省略分号:

my @sqrt_results
    = map { sqrt $_ } @results;

而无须写成这样:

my @sqrt_results
    = map { sqrt $_; } @results;

map或grep不会发生前述的问题,因为map、grep中的代码快通常只有一行代码。 如果你的map或grep代码块中包含多于一句代码,那只能说明这里不适合使用map或者grep。

2.8. 逗号

多行的列表的每一行末尾都要加逗号。

例如,下面例子最后一行的’Doc’后面也要加上逗号:

my @dwarves = (
    'Happy',
    'Sleepy',
    'Dopey',
    'Sneezy',
    'Grumpy',
    'Bashful',
    'Doc',
);

因为这样很容易通过sort命令对列表进行排序,而且添加新值时 也不会因为忘记逗号而出错。 如果Doc后面不加逗号,那么排序后就变成了

my @dwarves = (
    'Bashful',
    'Doc'
    'Dopey',
    'Grumpy',
    'Happy',
    'Sleepy',
    'Sneezy',
);