2010年8月30日月曜日

Perl best practices[Perlベストプラクティス] 2章 コードのレイアウト



自分用なので、
自分が普段からすでに習慣にしていることは記述しない。


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参照





Perl best practices[Perlベストプラクティス] 3章 命名規則



まず文法規則を作り、それを守る。
Perlの文法概要は、CPANのPare::RecDescentモジュール付属のtutorial.html参照。

パッケージやクラス名の命名


<名前空間> =>   <名詞> :: <形容詞> :: <形容詞>
or <名詞> :: <形容詞>
or <名詞>
ただし、この階層関係はPerlで自動で反映されるものではない。
以下のように明示的に示す。

package Disk;

package Disk::DVD;
use base qw( Disk );

package Disk::DVD::Rewritable;
use base qw( Disk::DVD );



変数名は具体的につける


複数のブロックで使用される変数の名前は、常に2つ以上の要素で構成される名前を付ける。
変数の名前は、[<形容詞> _ ]* <名詞>のように、0個以上の形容詞を名詞の前に付ける。
例えば、$total_scoreではなく、$running_totalにすると、途中の累計スコアを追跡していることが分かる。

参照テーブルには前置詞を用いる


参照テーブルに使われるハッシュや配列は名詞の最後に前置詞を追加する。
[<形容詞> _]* <名詞> <前置詞>

my %title_of;
my %ISBN_for;
my @sales_from;

for my $book ( @catalog ) {
print "$ISBN_for{$book}  $title_of{$book}: $sales_from{$month}\n";
}



サブルーチンやメソッドの命名


動詞 + 0回以上の形容詞 + 名詞 + (必要ならば、前置詞or分詞)

sub get_record;          #動詞、名詞
sub get_record_for;      #動詞、名詞、前置詞

sub eat_cookie;          #動詞、名詞
sub eat_previous_cookie; #動詞、形容詞、名詞

sub build_profile;                  #動詞、名詞
sub build_execution_profile;        #動詞、形容詞、名詞
sub build_execution_profile_using;  #動詞、形容詞、名詞、分詞



ブール値


基本的には、is_かhas_で始まることが多い。
以下の名前は自分でも使えそうなので、覚えておこう。

sub is_valid;
sub metadata_available_for;
sub has_end_tag;



参照変数には_refをつける


語尾に_refをつける。
僕は、頭にref_を付けてましたが、refの後にすぐに矢印参照があるほうがいいということのようです。(Perl6でなくなるようですが)

配列は複数形とハッシュは単数形


まとめて反復的に処理される配列は複数形の名前を。
ハッシュは、個別にアクセスされることが多いので単数形。
使い方に合わせて、例外あり。

変数の名前つなぎはアンダースコアを使う。


英語はスペースで区切られているが、アンダースコアの存在のなさがスペースに近い印象を与えるため。InterCaps方式は読みにくいし、すべて大文字の場合がうまくいかない。

大文字の使い分け



  1. サブルーチン、メソッド、変数、ラベル付きの引数の名前は小文字のみ

  2. パッケージ名とクラス名には、大文字と小文字を組み合わせる。

  3. 定数には大文字を使用

my $controller
= IO::controller->new(src=>$fh,  mode=>$SRC|$NODE);


固有名詞や、標準略語、単位などの識別子には当てはまらない。

略記は先頭部で示す


先頭のほうの母音などを削ると読みにくい。
length=>len ならわかるけど、 lnghだと分からない。
最後の子音が複数形を表すものは残してもいい。$orig_strs,prefix()など。
また、一般的に広く使われいる名前は例外とする。

意味がわからない略記はしない



  • val

    • value? valid?_

  • temp

    • temperature? temporary?

  • dev

    • device? deviation?

  • left

    • 方向か、残りか

  • right

    • 方向か、正しいのか、権利か

  • no

    • 否定か、ナンバーか

  • abstract

    • 理論的であることか、概略か、要約か

  • contract

    • 短縮か、法的契約か

  • record

    • 最高結果か、データ集合か、記録することか

  • second

    • 2番目か、秒か

  • close

    • 近いのか、閉じているのか

  • bases

    • 複数の基数か、複数の基準か



ユーティリティサブルーチン


モジュールからエクスポートしたり、クライアントが使用しない、内部使用専用のサブルーチンは先頭にアンダースコアを付ける。




2010年8月24日火曜日

aptitudeとapt-getの違い





ゆるperl#2に行ってきました



おもしろかったです。
知らない単語を知れる機会はいいですね。
StrawberryPerlとか知らんかった!

perlの話題はあんまりなかったです。
たぶんネタが投下されなかったせいでしょうね。

LTじゃないですけど、ソースコードなりなんなり、目的がいるかもしれませんねー。





2010年8月14日土曜日

ブラウザ上で各種言語を実行する



メモメモ。ってBrainf**kに対応してるんですかw

PHP、Perl、Ruby、C、C++等40以上の言語をブラウザで実行できるようになるjQueryプラグイン「Run This」



ここ重要



このサービスは、ideone.com というサイトのAPIを使っているようで、JavaScript が言語をパースするわけでなく、APIに投げて結果を表示する仕組みのようです。