13 September 2005
This post may be outdated due to it was written on 2005. The links may be broken. The code may be not working anymore. Leave comments if needed.
  • use Readonly instead of use constant.
    用 use Readonly 来代替 use constant

原因有二:一是 use constant 不能内插。例如:

# 用 Readonly 的两个例子
use Readonly;
Readonly my $DEAR      => 'Greetings to you,';
Readonly my $SINCERELY => 'May Heaven guard you from all misfortune,';

$msg = <<"END_MSG";
$DEAR $target_name

$scam_pitch

$SINCERELY

$fake_name
END_MSG

Readonly my $LINES_PER_PAGE => 42;
$margin{$LINES_PER_PAGE}                 # sets $margin{'42'}
    = $MAX_LINES - $LINES_PER_PAGE;
# 对应麻烦的用 constant
use constant (
    DEAR      => 'Greetings to you,',
    SINCERELY => 'May Heaven guard you from all misfortune,',
);

$msg = DEAR . $target_name
       . "$scam_pitch\n\n"
       . SINCERELY
       . "\n\n$fake_name";

use constant (
    LINES_PER_PAGE => 42
);

$margin{LINES_PER_PAGE}               # sets $margin{'LINES_PER_PAGE'}
    = MAX_LINES - LINES_PER_PAGE;

第二个原因是作用域范围。Readonly 能定义不同的作用域,而 constant 只有包作用域。

  • If you're forced to modify a package variable, localize it.
    如果需要改变一个包变量,请直接 local.
use YAML;

# Do
local $YAML::Indent = 4;

# NOT
$YAML::Indent = 4;

注意要初始化此变量。当 local 此变量时,它的值默认为 undef.

local $YAML::Indent; # 这里的值为 undef
local $YAML::Indent = $YAML::Indent; # 这样才可能是你想要的
  • Avoid subscripting arrays or hashes within loops.
    避免在循环中使用下标数组或散列。
# Do
for my $client (@clients) {
    $client->tally_hours(  );
    $client->bill_hours(  );
    $client->reset_hours(  );
}

# Do NOT
for my $n (0..$#clients) {
    $clients[$n]->tally_hours(  );
    $clients[$n]->bill_hours(  );
    $clients[$n]->reset_hours(  );
}
  • Use grep instead of for when searching for values in a list.
    当在列表中搜寻值时,首先考虑 grep 而不是 for.
    Use for instead of map when transforming a list in place.
    当在列表中改变其中的值时,首先考虑 for 而不是 map.
  • Use scalar reverse to reverse a scalar.
    使用 scalar reverse 来反转一个标量。
    在某些情况下,前面不加 scalar 也是可以成功的,但是很容易造成错误。如:
# 下两句是一样效果的
my $visible_email_address = reverse $actual_email_address;
my $visible_email_address = scalar reverse $actual_email_address;

# 但这两句效果不一样,子程序默认接受数组。所以可能就没有达到你要的目的。
add_email_addr(reverse $email_address); # 列表环境
add_email_addr(scalar reverse $email_address); # 标量环境
  • 对于在 sort 中重复运行多次的函数,考虑使用用散列缓存函数运行结果或使用 Memoize
# 对于如下代码
Use Digest::SHA qw( sha512 );

# Sort by SHA-512 digest of scripts
@sorted_scripts
    = sort { sha512($a) cmp sha512($b) } @scripts;

# 请用下面两则代替
my %sha512_of;

# Sort by SHA-512 digest of scripts
@sorted_scripts
    = sort { ($sha512_of{$a} ||= sha512($a))
                     cmp
             ($sha512_of{$b} ||= sha512($b))
           }
           @scripts;

# 或者更简洁
# Make the SHA-512 digest function self-caching...
use Memoize;
memoize('sha512');

# Sort by auto-cached SHA-512 digest of scripts...
@sorted_scripts = sort { sha512($a) cmp sha512($b) } @scripts;

Damain 还推荐了 Sort::Maker 来执行相关 sort 任务。

Finally

说实话我对英文也不是很感冒,所以读起来也是跳着读的。没怎么仔细看。所以也就这样了。


blog comments powered by Disqus