perlstyle - Perl スタイルガイド
プログラマは、もちろん人それぞれ、フォーマットには好みがあるでしょう。 しかし、いくつかのガイドラインに従うことによって、プログラムの可読性や 保守性をあげることができます。
もっとも重要なことは、つねにプログラムを -w フラグをつけて 走らせることです。 必要であれば、no warnings
プラグマや $^W
変数を使用してコードの 一部だけで警告を明示的にオフにします。 また、つねに use strict
を使用すべきです。 もし、use strict
を使用しないなら、その理由を十分に理解しておくべきです。 use sigtrap
や use diagnostics
プラグマも便利でしょう。
コードレイアウトの美観に関しては、Larry が強く気にかけているのはたった一つ、 複数行の BLOCK の閉じ中かっこは、その構造を開始したキーワードと同じ位置に なくてはならないということだけです。 それは別として、そこまで強くはない彼の好みは以下の通りです:
4 カラムのインデント。
可能なら、開始中かっことキーワードを同一行に。 そうでなければ、開始をそろえる。
複数行 BLOCK の開始中かっこの前にスペース。
1 行の BLOCK は中かっこも含め、1 行で。
セミコロンの前に空白なし。
"短い" 1 行 BLOCK ではセミコロンを省略。
ほとんどの演算子の前後にはスペース。
"複雑な"代入(ブラケット内)の前後にはスペース。
異なることをするチャンクの間には空行。
else をくっつけない。
関数名と開始カッコの間にはスペースなし。
カンマの後ろにはスペース。
長い行は、演算子の後ろで改行する(and
と or
を除く)。
行の最後のカッコの後ろにスペース。
対応する要素の開始位置をそろえる。
冗長な表現は、わかりにくくならない限りは省略する。
Larry にはこれらそれぞれを好む理由がありますが、彼以外の人がこれとまったく 同じである必要はないといっています。
他に、より重要なスタイルの問題を示します:
何かをある方法で できる からといって、そう すべき とは限りません。 Perl は一つのことを様々な方法でできるように設計されていますから、より 読みやすいものを選ぶように心がけてください。 たとえば、
open(FOO,$foo) || die "Can't open $foo: $!";
というのは以下のものより良いです:
die "Can't open $foo: $!" unless open(FOO,$foo);
なぜなら、2 つ目では、この文の主要部が修飾子に隠れてしまっています。 逆に、
print "Starting analysis\n" if $verbose;
というのは以下のものより良いです:
$verbose && print "Starting analysis\n";
この文の主要部は、ユーザが -v をタイプしたかどうか ではないからです。
同様に、ある演算子がデフォルト引数を想定しているからといって、その デフォルトを使わなくてはならないということにはなりません。 このデフォルト値があるのは、怠惰なシステムプログラマが、一発プログラムを 書くときのためにあります。 プログラムを読みやすくするには、引数を省略しないようにしましょう。
同様に、多くの場所でカッコを省略 できます が、以下のように 省略しすぎることは控えるべきでしょう:
return print reverse sort num values %array;
return print(reverse(sort num (values(%array))));
迷ったときは、カッコを書いてください。 少なくとも、間違えた部分は vi の % キーでハイライトすることができます。
迷っていないときも、あとでそのコードをメンテナンスする人の生活を 考えてください。 間違った個所にカッコをいれてしまうかもしれません。
ループの先頭や末尾で抜け出すのに、ばかげたコードをかかないでください。 Perl には last
演算子があるので、途中で抜け出すことができます。 ちょっとだけ読みやすくするには "アウトデント" します:
LINE:
for (;;) {
statements;
last LINE if $foo;
next LINE if /^#/;
statements;
}
ループのラベルは積極的に使いましょう -- 可読性をあげるのと共に、多段階の ループ抜け出しもできるようになります。 先ほどの例を見てください。
grep()
(や map()
)、また `逆クォート` を無効コンテキスト、つまり 返り値を無視する文で使用しないでください。 これらの関数はすべて返り値を持っていますから、それを使用してください。 いらないのであれば、foreach()
ループや system()
関数を 使用してください。
ポータビリティのために、すべてのマシンで実装されていないかもしれない機能を 使用する際は、それを eval で囲って、失敗するかどうかチェックしてください。 ある機能が、どのバージョンやパッチレベルで実装されているか知っている 場合には、$]
(English
モジュールでは、$PERL_VERSION
) を チェックすることもできます。 Config
モジュールを使えば、Perl インストール時の Configure
プログラムに よって決定された値を調べることができます。
ニーモニックな識別子を選んでください。 そのニーモニックが何を意味するか思い出せなければ、問題です。
$gotit
のような短い識別子なら ok ですが、より長い識別子の単語を 区切るにはアンダースコアを使用してください。 一般的には、とくに英語のネイティブスピーカーでない人にとっては、 $var_names_like_this
の方が $VarNamesLikeThis
より読みやすいです。 このルールは VAR_NAMES_LIKE_THIS
についても同様に当てはまります。
パッケージ名は、このルールの例外になることがあります。 Perl は小文字のモジュール名を、integer
や strict
のような"プラグマ" モジュールのために予約しています。 その他のモジュールは大文字からはじめて、小文字を混ぜて使用すべきですが、 アンダースコアは使用しません。 プリミティブなファイルシステムでは、モジュール名をファイルとして 表現する際に、バイト数の制限があるためです。
変数のスコープや性質を表現するのに、大文字小文字を使うと便利でしょう。 たとえば:
$ALL_CAPS_HERE 定数のみ (perl 変数との衝突に注意!)
$Some_Caps_Here パッケージワイドなグローバル/スタティック変数
$no_caps_here 関数スコープの my(),local()変数
関数とメソッドの名前はすべて小文字だとベストです。 例えば、$obj->as_string()
。
先頭にアンダースコアをつけることによって、変数や関数を定義したパッケージ外で 使用すべきでないことを示すことができます。
ほんとにごちゃごちゃな正規表現を使う場合には、/x
修飾子を使用して スペースをいれ、ごみみたいにならないようにしてください。 正規表現内にスラッシュやバックスラッシュがあるときには、デリミタに スラッシュを使わないように。
新しい and
と or
演算子を使用し、リスト演算子のカッコがたくさんに なったり、&&
や ||
が大量発生するのを避けてください。 サブルーチンは、関数やリスト演算子であるかのように扱い、アンパサンドや カッコが大量発生するのを避けてください。
print()
文を繰り返さず、ヒアドキュメントを使用してください。
対応するものの開始位置はそろえてください、とくに、1行におさまらないものに 関して。
$IDX = $ST_MTIME;
$IDX = $ST_ATIME if $opt_u;
$IDX = $ST_CTIME if $opt_c;
$IDX = $ST_SIZE if $opt_s;
mkdir $tmpdir, 0700 or die "can't mkdir $tmpdir: $!";
chdir($tmpdir) or die "can't chdir $tmpdir: $!";
mkdir 'tmp', 0777 or die "can't mkdir $tmpdir/tmp: $!";
システムコールの返りコードはつねにチェックしてください。 良いエラーメッセージは STDERR
に書き出され、問題を発生させた プログラム名や、失敗したシステムコールと引数、そして(とても重要)標準 システムエラーメッセージを含むべきです。 以下はシンプルですが、十分な例です:
opendir(D, $dir) or die "can't opendir $dir: $!";
見やすくなる場合には、tr の開始位置をそろえてください。
tr [abc]
[xyz];
再利用性を考慮しましょう。 同じことをあとでやるかもしれないときに、脳の力を一発のプログラムで 無駄にする必要はありますか? コードの一般化を考慮し、モジュールやオブジェクトクラスを書くことを 考慮しましょう。 コードが use strict
と use warnings
(あるいは -w) が有効でも きちんと動くか考慮しましょう。 コードを捨て去ることも考慮しましょう。 世界の見方を変えることを考慮しましょう。 他にも……ああ、もういいや。
あなたのコードを文書化して、一貫した方法で Pod フォーマットを使うように 努力してください。 以下は広く想定されている慣習です:
関数名、変数名、モジュール名(およびより一般的には、ファイルハンドルや 特定の値のような、コードの一部と考えられるもの)には C<>
を 使ってください。 関数名は、function()
のように、名前の後ろにかっこを付けると より読みやすくなると考えられています。
cat や grep のようなコマンド名には B<>
を使ってください。
ファイル名には F<>
か C<>
を使ってください。 F<>
はファイル名のための唯一の Pod コードであるべきですが、 ほとんどの Pod フォーマッタはこれをイタリック体で表示するため、 Unix と Windows でパスに使われるスラッシュや逆スラッシュが読みにくいです; C<>
はよりよく表示されます。
つねに一貫性を。
つねに素敵に。