Tips from Perl Best Practices
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