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<>
はよりよく表示されます。
つねに一貫性を。
つねに素敵に。