標籤:
第四章:值和運算式
資料是缺乏生氣的……
有點像程式員。
— Arthur Norman 零三三.
只對實際會插入的字串使用插入用字串界定符。
l 建立字串直接量而且想插入變數,使用雙引號括住的字串
my $spam_name = “$title$first_name $surname”;
l 建立字串直接量而且不想插入任何變數,使用單引號括住的字串
my $spam_name = ‘DrLawrence Mwalle’;
l 如果無插入(uninterpolated)字串本身包含單引號直接量,就改用q{…}的形式:
my $spam_name =q{r Lawrence (‘Larry’) Mwalle};
l 不要把反斜線(\)作為引號定界符;這樣只會讓內容和容器難以區分:
my $spam_name = ‘Dr Lawrence (\’Larry\’) Mwalle’;
l 如果無插入字串包含單引號直接量以及不平衡的大括弧,就改用中括弧作為定界符:
my $spam_name =q[Dr Lawrence ] Larry{ Mwalle}; 零三肆.
Null 字元串不要用””或’’。
$error_msg= q{}; 零三伍.
不要用視覺上會產生模糊的方式編寫單字元字串。 零三陸.
使用具名字字元轉義,不要使用數值轉義。
通過use charnames指令(pragma)
usecharnames qw( :full);
$escape_seq= “\N{DELETE}\N{ACKNOWLEDGE}\N{CANCEL}Z”; 零三柒.
使用具名常量,不要使用use constant。
純粹的數字突然出現在程式中間通常都很神秘、時常令人困惑,而且都是潛在的錯誤源頭。
把這種純粹的數字直接量換成唯讀詞法變數,而以變數名詞說明該數位意義:
useReadonly;
Readonlymy $MOLYBDENUM_ATOMIC_NUMBER => 42;
#稍後 ……
print$count * $MOLYBDENUM_ATOMIC_NUMBER; 零三捌.
不要以前置字元為零替十進位數補位。
如果你必須指定八位元值,就用內建的oct函數,例如:
useReadonly;
Readonlymy %PERMISSIONS_FOR => (
USER_ONLY => oct(600),
NORMAL_ACCESS => oct(644),
ALL_ACCESS => oct(666)
); 零三玖.
使用底線改進長數位可讀性。
use bignum;
$PI =3.141592_653589_793238_462643_383279_502884_197169_399375;
$subnet_mask = 0xFF_FF_FF_80; 零肆零.
在多行上部署多行字串。
如果字串內有換行字元,而整個字串無法在一行內排完,就應該在每個換行字元之後斷開,再將那幾段串聯起來:
$usage= “Usage: $0 <file>[-full]\n”
.“(Use –full option for full dump)\n”
; 零肆壹.
當多行字串超過兩行時,就使用heredoc(Here Document)。
對少數幾行而言,“在新行之後斷開再串聯”的方法很適合,但是對大段的文字而言,就會開始變得沒有效率和難看。
對超過兩行的多行字串而言,就改用heredoc:
$usage= <<“END_USAGE;
Usage: : $0 <file> [-full] [-o] [-beans]”
Options:
-full : produce a full dump
-o : dump in octal
-beans : source is Java
END_USAGE 零肆貳.
當heredoc危及你的縮排時,就改用“theredoc”。
較佳的實踐是把這類heredoc分離出來,放進預定義常量或子程式內(“theredoc”):
useReadonly;
Readonlymy $USAGE => <<’END_USAGE’;
Usage: qdump <file> [-full] [-o] [-beans]”
Options:
-full : produce a full dump
-o : dump in octal
-beans : source is Java
END_USAGE
#稍後……
if($usage_error) {
warn$USAGE;
} 零肆三.
每個heredoc中止符號都做成單一大寫標識符,而且帶有標準的首碼。
print<<’END_LIST’;
getname
setsize
putnext
END_LIST 零肆肆.
引入heredoc時以引號標示終止符號。
注意,在前幾條指導方針的heredoc範例中,都在<<之後使用單引號或雙引號。
以單引號括起此標示符號,會強迫heredoc不去插入任何變數。
以雙引號括起此標示符號,就會確保heredoc字串會被插入任何變數。 零肆伍.
不要使用未修飾字(bareword)。
strict 指令會在編譯期間檢查出任何未修飾字:
usestrict ‘subs’;
[email protected] = map {sqrt $_} 0..100;
formy $N (2, 3, 5, 8, 13, 21, 34, 55) {
print$sqrt[N], “\n”;
}
然後拋出異常:
Bareword“N” not allowed while “strict subs” in use at sqrts.pl line 5 零肆陸.
保留=>給成對的東西使用。
每當你建立 鍵—值、明—值的列表時,都要使用“胖逗號”(即=>, fat comma)來把鍵與其相應的值聯絡起來。例如,構建散列時就可用到:
%default_service_record= (
name => ‘<unknown>’,
rank => ‘Recruit’,
serial => undef
); 零肆柒.
不要用逗號排序語句。
有C/C++背景的Perl程式員習慣在Perl程式中寫出C風格的for迴圈:
# 二分尋找(binary chop)搜尋 ……
SEARCH:
for($min = 0, $max = $#samples, $found_target = 0; $min <= $max; ) {
$pos= int(($max + $min) / 2);
my$test_val = $samples[$pos];
if($target == $test_val) {
$found_target= 1;
lastSEARCH;
}
elsif($target < $test_val) {
$max= $pos - 1;
}
else{
$min= $pos + 1;
}
}
正確的是:
# 二分尋找(binary chop)搜尋 ……
SEARCH:
for(do{$min = 0, $max = $#samples, $found_target = 0;}; $min <= $max; ) {
# 同前例
}
print‘Sir’,
do{check_name($name); $name;},
‘,KBE’; 零肆捌.
不要把高低優先順序的布爾運算混在一起。
為了讓條件測試的理解度提升到最大,要完全避免and和not,然後只把低優先順序的or保留給易出錯的內建函數使用以指定“退路”(fallbackposition):
open my $source, ‘<’, $source_file
or croak “Couldn’t access sourcecode: $OS_ERROR”; 零肆玖.
每個原始列表都要以小括弧括起來。
@todo= (‘Patent concept of 1 and 0’, ‘Sue Microsoft and IBM’, ‘Profit!’); 零伍零.
使用表格尋找來測試字串列表中的成員關係;
使用any() 測試任何其他東西的列表的成員關係。
#索引編號是否已被取走?
if(any {$requeste_slot == $_ } @allocated_slots ) {
print“Slot $requested_slot is already taken. Please select another:”;
redoGET_SLOT;
}
如果你的列表成員關係測試使用eq,就不要使用any(),最好改用尋找表:
Readonly my %IS_EXIT_WORD
=map { ($_ => 1) } qw(
Qquit bye exit stop done last finish aurevoir
);
稍後 ……
if( $IS_EXIT_WORD{$cmd} ) {
abort_run();
}
Perl 最佳實務(節選) --- 04