Category: BookNotes Keywords: tips
- 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 任务。