Perl Hackers Hub

第8回 Perlによる大規模システム開発・設計のツボ(1)

この記事を読むのに必要な時間:およそ 4 分

本連載では第一線のPerlハッカーが回替わりで執筆していきます。今回のハッカーはmixiの広木大地さんで,テーマは「大規模システム開発・設計のツボ」です。

仕事やOSSOpen Source SoftwareプロジェクトでPerlを用いた多人数開発をするにあたって気をつけるべきことや,品質を維持するためのノウハウを,国内最大級のPerlシステムであるmixiの事例をベースに紹介します。コーディング上の命名に関する考え方から,大規模アーキテクチャの設計や品質の数値化まで,ミクロからマクロに至るポリシーやテクニックを駆け足で解説します。

なお,今回の内容は⁠株⁠ミクシィの2010年度の新卒エンジニア技術教育メニューからの抜粋になります。これからPerl をはじめとするLLLightweight Language軽量言語)を仕事で使うというフレッシュエンジニアのみなさんにも,ぜひご一読いただけたらと思います。

コードはコミュニケーションツール

「コミュニケーション能力」は社会人にとって重要な資質とされています。プログラマにとって重要なコミュニケーション能力の一つに,コードの意図を正確に同僚や未来の自分に伝えることがあります。意図のわかりづらいコードや入り組んだコードは,それだけで周囲のプログラマやプロジェクトに迷惑をかけてしまうかもしれません。

コードの命名

コードの意図を正しく伝えるためには,何よりも命名するという行為に注意を払う必要があります。Perlスクリプト中に存在する「あなたが命名するもの」には,次のようなものがあります。

  • パッケージ名/クラス名/メソッド名
  • DBカラム名/テーブル名
  • サービスのURI
  • グローバル/レキシカル変数名

このように見ると予約語,CPANモジュール,同僚のメンテしているライブラリなどを除いて,ほぼすべてがあなたが付けた名前です。プログラミングという行為は,そのほとんどが名前を付けることと言っても過言ではないかもしれません。

不明瞭な名前,マジックナンバーを避ける

適切に名付けられていないコードは意図が読み取りづらいものになりがちです。

sub calculate {
    my ( $ctgry,$t ) = @_;
    if( $ctgry == 1 ) {
        return $t * hourly($ctgry) * ( 1 + 0.23);
    } else {
        return $t * hourly($ctgry);
    }
}

上記のコードはロジックとしてはとてもシンプルでわかりやすいのですが,何をするためにどんな意図で作られたのかがわかりません。具体的にはたとえば次のような不明確な点があります。

  • 1や0.23など裸の数字が何を意味しているかわからない
  • 引数がどのようなものかよくわからない
  • 関数名が一般的過ぎて何をしたいのかよくわからない

1点目のようなプログラム中の裸の数字は「マジックナンバー」と呼ばれています。文脈が不明瞭になるため基本的に避けたほうがよいです。

上記のコードを文脈が明らかになるように書き換えてみましょう。

use constant WHITE_WORKER => 1;
use constant BLUE_WORKER => 2;
use constant INCREASING_RATE => 1 + 0.23;

sub get_wages {
    my ( $user_category,$working_hours ) = @_;
    if( $user_category == WHITE_WORKER ) {
        return $working_hours *
               wages_an_hour($user_category) *
               INCREASING_RATE;
    } else {
        return $working_hours *
               wages_on_hour($user_category);
    }
}

このようにすると,一見するだけで時給の計算をしている関数だと理解できます。プログラム中に含まれる数字,フラグなどには必ず意味があります。意味のあるものにはその意味を名前として与えましょう。

バグを誘発しやすい変数名

関数スコープ内のレキシカル変数も重要な名前です。この名前の付け方一つで,バグを引き起こしたり読解が困難になるなど,さまざまな悪影響が生じます。

my $item_1; my $item_2; my $item_3;

上記のように連番で定義された変数は,リストとして定義するか,名前で明瞭な意味を表しましょう。

my @items;
my ($head,$body,$tail);

ほかにも,次のような名前の変数は明快さに欠けています。

my $item;
my %item;
my @item;

それぞれ異なるシジル注1で,同じ名前の変数が定義されています。Perlではこれらは別の変数と認識されますが,同一の関数の中で異なるデータ構造が同じ名前で同居している状態は,ミスタイプや勘違い,誤読を誘発します。

次のように,それぞれのデータ構造に合った名前にすることで,区別が付きやすくなります。

my $item;
my %name_to_item;
my @items;
my @item_list;

ぱっと良い名前が思いつかないときに先のような変数名を付けてしまいがちですが,多少長くなっても意図のはっきりした名前を付けることで,メンテナンス性が格段に向上します。

注1)
$,%,@などの変数の接頭辞のことです。

著者プロフィール

広木大地(ひろきだいち)

筑波大学大学院卒業後,2008年度に新卒として株式会社ミクシィに入社。

広告システムの開発に従事したのち,システム本部たんぽぽ開発グループに所属。現在は「刺身の上にたんぽぽを乗せる仕事」を撲滅するべく,サービスアーキテクチャの設計/開発や技術者教育などを担当している。

YAPC::Asia 2010にて,mixiのアーキテクチャについての発表を行った。

コメント

コメントの記入