ポストフィックス形式のif文は制御フロー文にのみ使用
LOOP:
for my $mem (@mems) {
last LOOP if $mem f < 0;
}
next,last,redo,return,goto,die,croak,throwキーワードは、目立つ左端にくるように、if文を後ろにもってくる。
ポストフィックス形式のunless,for,while,untillを使用しない
- 特にfor文は、ポストフィックス形式は使わない。
- 反復子変数に$_を使う必要がある。
- 評価式を簡単にはネストできない
- 後からfor文が肥大化すると、ポストフィックス形式は無理がある。初めから使わない。
否定制御文(unless,untill)を使用しない
- 拡張が難しい
- 2重否定を理解するのが難しい
- 否定制御文(unlessf)を否定演算子(!)に置き換えた場合、以降の条件をすべて反転させないといけない
- もし否定制御文を使用する場合は、コードが見やすくなる場合だけにする
- このとき、否定制御文の条件式は、肯定的なものにすること。
Cスタイルのループを使用しない
- C言語のループは素直に読みにくい
以下のCスタイルのループは、読み手がロジックを解明する必要があるが、2番目のループは、やりたいことがそのまま書いてある。
for (my $n=4; $n<=$MAX; $n+=2) {
print $result[$n];
}
RESULT:
for my $n (4..$MAX) {
next RESULT if odd($n);#ベンチマークでパフォーマンスに問題ありならn%2を使用
print $result[$n];
}
また反復カウント用変数や条件式が2つ以上ある場合、または、反復カウンタ変数が線形に変化しない場合はwhile文を使う。(139ページ参照)
values関数から得られるリストは、エイリアスのリストである
エイリアスなので、実際のハッシュ値を書き換える。
ただし、delete関数だけは値のエイリアスでは不十分で、キーも知る必要がある。
この場合は、5章で解説されたハッシュスライスを使う。
my @unacceptable_words
= grep {$translation_for{$_} =~ m/ $PROFANITY /xms}
keys %translation_for;
delete @translation_for{@unacceptable_words};#スライスでdelete
反復にインデックスと値の両方が必要なときは、エイリアス化する
use Data::Alias;
for my $agent_num (0..$#operatives) {
alias my $agent = $operatives[$agent_num];
if($on_disavowed_list{$agent}) {
$agent = '[DISAVOWED]'; #エイリアス化してないと、ここでインデックスが必要になる
}
ハッシュの場合も同じ手法を用いる。
しかしeach関数はこの手法は仕えない。each関数で返される値は、ハッシュ値のエイリアスではなくコピーである。
非レキシカルループ反復子
my $client;
SEARCH:
for $client (@clients) { #forスコープ
last SEARCH if $client->holding();
}
if ($client) {#forの反復カウンタは常に破棄されるので、取得は不可能
$client->resume_conversation();
}
for文の$clientは、forのスコープで新しくこっそり作られたレキシカル変数であり、その前の$clientとは関係ない。ここで、for my $clientとしていれば、読み手に分かりやすく伝えることができる。(もちろん違う名前のほうがいい)
リストからリストの生成するには、mapを使用する
ある配列の要素を2乗して新しい配列に、反復で一つずつpushするコードでは、pushする度にメモリの再割当てが必要になる。
しかしmapは、事前に必要な要素数を把握する。(1つの要素から複数の要素を生成する場合は別)
またmapは、高速なCコードで処理される。
リスト値の検索はmapかfirstを使う
forの代わりに使うと、理解しやすい効率的なコードになる。
変換先と変換元の配列が同じ場合はmapではなくforを使う
mapは追加メモリを割り当てたあとに、一時的に保持していたリストを代入するが、forは変換元リストの既存のメモリを再利用できる。
複雑なマッピング
複雑な反復にコードが肥大化したときは、関数に避けて、単純なmap式から呼び出す。
リスト関数で$_を変更しない
$_はエイリアスなので、もとの値が変更されてしまう。分かりにくいコードになる。
0 件のコメント:
コメントを投稿