自分用なので、
自分が普段からすでに習慣にしていることは記述しない。
if,forなどの制御キーワードとサブルーチン呼び出し、変数名を区別し易くする
制御キーワードの後と、{ の前はスペースを入れる。
while[一つスペース](....)[ひとつスペース]{
}
サブルーチン呼び出しや、変数は後続の括弧との間にスペースを入れない。
ただし、配列のインデックスが定数かスカラー変数以外のときは、インデックス式とそれを囲む括弧との間にスペースを入れる。
my @candidates = get_candidates($marker);
CANDIDATE:
for my $i (0..$#candidates) {
next CANDIDATE if open_region($i);
$candidate[$i]
= $incumbent{ $candidates[$i]{region} }; #<-インデックスはスペース有り
}
組み込み関数とサブルーチンを区別し易くする
組み込み関数は優先度を指定する必要がない場合は、括弧を使わないことで、サブルーチンと見分ける。
括弧を使用する場合は、サブルーチンと同じく、括弧との間にスペースを入れない。
○ split("\t", $record);
× split ("\t", $record);
また、事実上、組み込み関数と呼べる名誉組み込み関数にもこのルールを適用する。
例えば、carp,croak(Carp標準モジュール)、first,max(List::Util標準モジュール)、prompt(IO::Prompt)が挙げられる。
リストには必ず、コンマを入れる。
順序を入れ替えた際にバグになるから。
my @dwarves = (
'Happy' ,
'Sleepy' ,
'Dopey' , #<=ここ注意
);
行の長さ、インデント、タブ
古いディスプレイや印刷文書のことを考えて、行の長さは78文字。
emacsでの設定は、
(setq fill-column 78)
(setq auto-fill-mode t)
インデントの深さは、一長一短。4文字くらいにしておく。
タブとスペースを混ぜるのは良くないので、タブを押したら、スペース4文字になるように設定する。
emacsでの設定は、
(defalias 'perl-mode 'cperl-mode)
;; cperlモードでのスペース4つのインデント
'(cperl-close-paren-offset -4)
'(cperl-continued-statement-offset 4)
'(cperl-indent-level 4)
'(cperl-indent-parens-as-block t)
'(cperl-tab-always-indent t)
タブがコード上に存在しないのが望ましい。
文字リテラルでは、\tを使って指定する。
複数文を1行にまとめない。
当たり前のようだが、注意したいのがmapを使用する場合。
my @clean_words
= map { my $word = $_; $word =~ s/$EXPLETIVE/[DELETED]/gxms; $word }
@raw_word;
my @clean_words
= map {
my $word = $_;
$word =~ s/$EXPLETIVE/[DELETED]/gxms;
$word
} @raw_word;
コードを段落に分ける。
これは無意識にみんなやってる気がする。
コードとコードの間には一行分隙間を設ける。
'}'とelseを同列に並べない
コードが段落としてきっちり分かれるようにする。
if () {
}
else {
}
対の項目は縦に整列させる。
my @months = wq(
January February March
April May June
July August September
);
my %expansion_of = (
q{it's} => q{it is},
q{we're} => q{we are},
q{must've} => q{must have},
)
$name = standardize_name($name);
$age = time - $birth_date;
$status = 'active';
$indent{ name } = standardize_name($name);
$indent{ age } = time -$birth_date;
$indent{ status } = 'active';
長い分の分割
長い式は、演算子の前で分割する。
また、継続行は、単純なインデントではなく、それが属している式の1列目でインデントする。
pushの2つの引数が横方向で分離されているため、見やすいコードになる。
またセミコロンだけで1行使う。読み手の視線は各行の先頭にそって、下へ移動するため、
式がそこで完了することがはっきりわかる。
push @steps, $step[-1]
+ $radial_velocity * $elapsed_time
+ $orbital_velocity * ($phase + $phase_shift)
- $DRAG_COEFF * $altiude
;
優先度が低い演算子で式を分割
優先順位が低い演算子で改行することで、1行ごとの式を、優先度の高い式のグループとして見ることができる。
push @steps, $step[-1]
+ $radial_velocity * $elapsed_time
+ $orbital_velocity
* ($phase + $phase_shift) #<= 優先順位が低くない演算子で改行する場合はインデント
- $DRAG_COEFF * $altitude
;
長い代入式は、代入演算子の前で分割する
$predicted_val[$current_data_set]{$next_iteration} =
$average + $predicted_change * fudge_factor;
代入先の変数名が長いと、右端までみないと代入演算子がない。
代入演算子で改行することで、代入先と代入演算子が視覚的に近くにくる。
$predicted_val[$current_data_set]{$next_iteration}
= $average + $predicted_change * fudge_factor;
のようにする。
演算子で分割する場合は
$predivted_val[$current_data_set]{$next_iteration}
= ($minimum + $maximum) / 2
+ $predicted_change * max($fudge_factor, $local_epsilon);
3項演算子はテーブルっぽく列でフォーマットする
my $salute = $name eq $EMPTY_STR ? 'Customer'
;
if-else文と比べた際のメリットは、
1、代入文が1つですむこと。代入先変数の名前の確認が一ヶ所ですむ。
2、if文よりも厳格な構文。必ずelse文が必要とされる。
3、テーブルのように見える。?と:が列の境界線のように見える。
長いリストはコンマでくくる。
for my $item (@requested_items) {
push @items, (
"A brand new $item",
"A fully refurbished $item",
);
}
リストのコンマは演算子ではないため、演算子の直前で改行するルールを適用しないこと。
自動レイアウト
perltidyを用いて、レイアウトを変換することができる。
設定例は、P37参照
0 件のコメント:
コメントを投稿