名前¶
perlstyle - Perl スタイルガイド
説明¶
プログラマは、もちろん人それぞれ、フォーマットには好みがあるでしょう。しかし、いくつかのガイドラインに従うことによって、プログラムの可読性や保守性をあげることができます。
もっとも重要なことは、つねにプログラムを-wフラグをつけて走らせることです。必要であれば、no warnings
プラグマや $^W
変数を使用してコードの一部だけで警告を明示的にオフにします。また、つねに use strict
を使用すべきです。もし、use strict
を使用しないなら、その理由を十分に理解しておくべきです。use sigtrap
や use diagnostics
プラグマも便利でしょう。
コードレイアウトの美観に関しては、Larry が強く気にかけているのはたった一つ、複数行のブロックの閉じブラケット、その構造を開始したキーワードと同じ位置になくてはならないということだけです。その他に、彼のあまり強くはない好みは以下の通りです:
4カラムのインデント。
可能なら、開始ブラケットとキーワードを同一行に。そうでなければ、開始をそろえる。
複数行ブロックの開始ブラケットの前にスペース。
1行のブロックはブラケットも含め、1行で。
セミコロンの前に空白なし。
"短い"1行ブロックではセミコロンを省略。
ほとんどの演算子の前後にはスペース。
"複雑な"代入(ブラケット内)の前後にはスペース
異なることをするチャンクの間には空行。
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())、また `バックティクス` を void コンテキスト、つまり返り値を無視する文で使用しないでください。これらの関数はすべて返り値を持っていますから、それを使用してください。いらないのであれば、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()変数
関数とメソッドの名前はすべて小文字だとベストです。E.g., $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) が有効でもきちんと動くか考慮しましょう。コードを捨て去ることも考慮しましょう。世界の見方を変えることを考慮しましょう。他にも……ああ、もういいや。つねに一貫性を。
つねに素敵に。