NAME

perlmodstyle - Perl モジュールスタイルガイド

INTRODUCTION

このドキュメントは Perl コミュニティにおける Perl モジュールを書くときの「ベストプラクティス」を 説明しています。 これは perlstyle にある推奨項目を拡張します; perlstyle はこのドキュメントに先立って目を通しておいてください。

このドキュメントは全てのモジュール作者に役立つように 意図していますが、CPAN にモジュールを公開しようと している作者を特に意図しています。

焦点は、モジュール開発者の目にとまる点ではなく、 モジュールのユーザの目にとまるスタイルの要素に置かれています。 しかし、このドキュメントであげられているガイドラインの 多くはモジュールの内部にも推測、適用できるでしょう。

perlnewmod は CPAN モジュールを作るためのチュートリアルであるのに対し、 この文書はスタイルに関するガイドという点で異なっています。 それはモジュールがベストプラクティスに沿っているかを これを成し遂げる方法を詳細に記述する必要なしに 決定するために比較するためのチェックリストを 提供しています。

このドキュメントに含まれる全てのアドバイスは 経験に富んだ CPAN 作者及びユーザの広範囲にわたる 議論から少しずつ集められています。 ここにあるアドバイスのどの欠片も以前の過ちの解決として 生まれました。 この情報は同じ過ちを繰り返さないように、 そして必然的にそれらを修正するという余計な作業が 必要とならないように、あなたを手助けするために ここにあります。

このドキュメントの最初のセクションでは項目別のチェックリストを 提供します; その後のセクションではリストの各項目について より詳しい説明を行います。 そして最後のセクション、「よくある落とし穴」で CPAN 作者が よくやってしまう、特にメジャーな失敗をいくつか説明します。

クイックチェックリスト

このチェックリストにおける各項目の詳細は後のセクションを 参照してください。

始める前に

API

安定性

ドキュメンテーション

リリース時に確認すること

モジュールを書き始める前に

最初に少し考える時間を取らずにモジュール開発に取りかかろうとしないで ください。 予め少し考えておくことで、後での多くの苦労を防げます。

以前作られていなかった?

そもそもモジュールを書く必要がないかもしれません。 既に Perl で行われているかどうかを調べて、よい理由がない限り 車輪の再発明は避けてください。

既にあるモジュールを探すのによい場所は、http://search.cpan.org/ と、 modules@perl.org に聞くことです。

もし既にあるモジュールがやりたいことを ほとんど しているなら、 それを書き直すのではなく、パッチを作ったり、派生クラスを作ったり、 あるいは既にあるモジュールを拡張するためのその他の手段を考慮してください。

一つのことをうまくやる

当たり前のことを述べるという危険を冒しますが、モジュールはモジュール式で あることを目的としています。 Perl 開発者は、自身のアプリケーションの建築ブロックを寄せ集めるために モジュールを使えるようにするべきです。 しかし、ブロックが正しい形をしていて、開発者が小さいブロックが必要な だけのときに大きいブロックを使う必要がないようにすることが重要です。

モジュールは、一文だけで表現できる明確に定義されたスコープを持つべきです。 あなたのモジュールは関係するモジュール群に分割できませんか?

悪い例:

「FooBar.pm は、FOO プロトコルと、関連する BAR 標準の実装を提供します。」

良い例:

「Foo.pm は FOO プロトコルの実装を提供します。 Bar.pm は関連する BAR プロトコルを実装します。」

これは、もし開発者が BAR 標準のモジュールだけを必要としているなら、 FOO ライブラリのインストールを強制されないということです。

なんて名前?

前もって、モジュールのための適切な名前を選んでください。 これは人々がモジュールを探したり覚えたりする助けになり、モジュールを 使ったプログラミングがより直観的になります。

モジュールに名前を付けるときには、以下のことを考慮してください:

モジュールを出版する前に、モジュール名について訊ねるために modules@perl.org に連絡するべきです。 また、すでにモジュールのアプリケーションドメインと CPAN 命名システムに 親しんでいる人々に尋ねてみるべきです。 同様なモジュールの作者や、似た名前のモジュールは始めるのに いいところでしょう。

モジュールの設計と作成

モジュールの設計とコーディングで考慮すること:

OO か非 OO か?

モジュールはオブジェクト指向 (OO) にするかしないか、あるいは両方の インターフェースを持つようにもできます。 それぞれの技術には、API を設計するときに検討するべき メリットデメリットがあります。

Perl ベストプラクティス(Perl Best Practices>) (2004 年、 オライリーメディアによって出版)で、Damian Conway は OO が問題を解決するのに 向いているかを判断するときに使う基準の一覧を提供しています:

あなたのモジュールに OO が適切かどうかを慎重に考えてください。 不必要なオブジェクト指向は、平均的なモジュール利用者が理解や使用するのが 困難な複雑な API となります。

API の設計

インターフェースは平均的な Perl プログラマが理解可能であるべきです。 以下のガイドラインは、API が充分に簡単かどうかを判断する手助けに なるでしょう:

単純なことをする単純なルーチンを書く。

少量の巨大なルーチンよりも、たくさんの単純なルーチンの方がよいです。 ルーチンが引数によって大きく振る舞いを変えるなら、複数のルーチンに 分割するべきと言うサインです。

機能を出力から分離する。

結果は出来るだけ一般的な形式で返して、ユーザがそれをどのように使うかを 選択できるようにします。 最も一般的な形式とは、おそらく後でテキストレポート、HTML、XML、 データベースクエリ、あるいはユーザが求めるもの何でも生成できる Perl データ構造です。

あなたのルーチンがある種のリスト(ファイルのリスト、データベースの レコードなど)に対して反復するなら、ユーザがリストのそれぞれの要素を 操作できるようなコールバックを提供することを考慮してください。 File::Find は find(\&wanted, $dir) という文法で、この場合の例を 提供しています。

実用的なショートカットやデフォルトを提供する。

単純な結果を得るために全てのモジュールユーザに同じ輪をくぐることを 要求しないようにしてください。 より複雑だったり標準でない振る舞いのためには、常にオプションの引数や ルーチンを用意して管浅い。 もしほとんどのユーザがモジュールを使い始めるときにほとんど同じ 数行のコードを書く必要があるなら、それはその振る舞いをデフォルトに するべきというサインです。 デフォルトを使うべきというもう一つの指標は、ユーザのほとんどが同じ引数で ルーチンを呼び出すときです。

命名規則

命名は一貫性を持たせるべきです。 例えば、以下のものは:

        display_day();
        display_week();
        display_year();

以下のものよりよいです:

        display_day();
        week_display();
        show_year();

これはメソッド名、引数名、その他ユーザに見えるもの何にでも (そして見えない物のほとんどにも!)適用されます。

引数の渡し方

名前付き引数を使いましょう。 これは以下のようにハッシュを使えば:

    $obj->do_something(
            name => "wibble",
            type => "text",
            size => 1024,
    );

…以下のように名前のない引数の長いリストより簡単です:

    $obj->do_something("wibble", "text", 1024);

引数のリストは 1 引数、2 引数、そして 3 引数でもうまく動作するでしょうが、 それ以上になるとモジュールユーザが覚えるのが難しくなり、モジュール 作者が管理するのも難しくなります。 新しい引数を追加したいときは、後方互換性のためにリストの最後に追加する 必要があり、そしてこれによっておそらくリストの順序が直観的では なくなるでしょう。 また、多くの要素が未定義の場合、以下のような美しくないメソッド呼び出しを 見ることになるでしょう:

    $obj->do_something(undef, undef, undef, undef, undef, 1024);

引数に、意味のあるデフォルトがあるならそれをデフォルトにしましょう。 ユーザーに、毎回ほとんど同じような引数を指定させてはいけません。

引数をハッシュで渡すかハッシュリファレンスで渡すかの問題は主に個人的な スタイルの問題です。

ハイフンで始まるハッシュキー (-name) や全て大文字のハッシュキー (NAME) は、普通の小文字の文字列が => 演算子で扱えなかった 古いバージョンの Perl の遺物です。 一部のモジュールでは歴史的な理由や個人的なスタイルの問題で大文字や ハイフン付きのキーのままですが、ほとんどの新しいモジュールは単純な 小文字のキーを使うべきです。 どちらを選ぶにせよ、一貫性を持ちましょう!

strict と warnings

モジュールは stirct プラグマ付きでも正しく動作し、一切の警告なしで 動作するべきです。 また、適切な場所では汚染チェックも扱うべきですが、これは多くの場合で困難を 伴います。

後方互換性

「安定版の」モジュールは、少なくとも長い移行フェーズとバージョン番号の メジャー番号の変更することなく、後方互換性を壊すべきではありません。

エラーハンドリングとメッセージ

モジュールがエラーに遭遇した場合、以下の一つあるいは複数を行うべきです:

設定可能なエラー処理はユーザーにとってとても便利です。 警告やデバッグメッセージのレベルの選択、メッセージの別のファイルへの書き出し、 エラー処理ルーチンの指定方法、あるいはその他の同様の機能の提供を 考慮してください。 これらのオプション全てのデフォルトは最も一般的な使用法に設定してください。

モジュールを文書化する

POD

モジュールは Perl の開発者向けの文書を含めるべきです。 一般的な技術文書に対しては Perl の "plain old documentation" (POD) を 使うべきですが、追加の文書 (ホワイトペーパー、チュートリアルなど) は その他のフォーマットで書きたいかもしれません。 以下のような主題に対応する必要があります:

Perl モジュール文書の詳細度は、一般的に概略から詳細へという順序に なっています。 SYNOPSIS 節には使うための最小限の例を含むべきです (おそらくは一行でしょう; 一般的でない使い方やほとんどのユーザーにとって 必要でないものは省略します); DESCRIPTION はモジュールを広義で記述し、一般的には単に数段落です; モジュールのルーチンやメソッドに関する更なる詳細、長いコード例、その他の より深い内容は引き続く節に書くべきです。

理想的には、モジュールに対して少しなじみのあるユーザーなら "page down" キーを 押すことなく記憶を思い出せるようにするべきです。 読者が文書を読み進めるにつれて、徐々に多くの量の知識を受け取ります。

推奨する Perl モジュール文書の章の順序は:

文書は、記述しているコードの近くになるように(「インライン」文書) 維持してください。 メソッドのための POD はメソッドのサブルーチンの直前に書いてください。 これにより文書を最新に保つのが容易になり、一つのコードに対して 2 箇所 (POD とコメント) に書く必要がなくなります。

README, INSTALL, リリースノート, changelogs

モジュールには、モジュールの説明と、さらなる情報へのポインタ (ウェブサイト、 作者への email) を記述した README ファイルも含めるべきです。

INSTALL ファイルを含めて、そこに簡単なインストール手順を記述するべきです。 ExtUtils::MakeMaker を使っているなら、これは普通は以下のようになります:

perl Makefile.PL
make
make test
make install

Module::Build を使っているなら、これは普通は以下のようになります:

perl Build.PL
perl Build
perl Build test
perl Build install

リリースノートまたは changelogs は、ユーザーからの観点でモジュールの ユーザーから見える変更点を記述して、リリース毎に作成するべきです。

他の形式を使う良い理由 (例えば、会社で使われている形式) がない限り、 変更履歴ファイルは Changes という名前にして、CPAN::Changes::Spec に ある単純な形式に従うのが慣習です。

RELEASE CONSIDERATIONS

バージョン番号

バージョン番号は少なくともメジャーリリースとマイナーリリース、そして 場合により副マイナーリリースを示すべきです。 メジャーリリースは、主な機能の変更や、あるいは主な新機能が 追加です。 マイナーリリースは機能の一部の追加や修正です。 副マイナーバージョン番号は普通、文書パッチのような機能に影響を与えない 変更に使われます。

最も一般的な CPAN のバージョン番号付け方式は次のようなものです:

    1.00, 1.10, 1.11, 1.20, 1.30, 1.31, 1.32

正しい CPAN バージョン番号は、小数点の後に少なくとも 2 桁の数字がある 浮動小数点数です。 CPAN に準拠しているかどうかは以下のようにしてテストできます

    perl -MExtUtils::MakeMaker -le 'print MM->parse_version(shift)' 'Foo.pm'

「ベータ」あるいは「アルファ」バージョンのモジュールをリリースしたいけれども CPAN.pm に最新版として扱ってほしくない場合、通常のバージョン番号の 後に '_' を使い、引き続いて最低 2 桁の数字を付けます; 例えば 1.20_01。 こうするなら、以下の慣用句が推奨されます:

  $VERSION = "1.12_01";
  $XS_VERSION = $VERSION; # only needed if you have XS code
  $VERSION = eval $VERSION;

この小技を使うと、MakeMaker は最初の行だけを読むので下線付きで読み、 一方 perl インタプリタは $VERSION を eval して文字列を数値に変換します。 これにより、後の操作で $VERSION を数値として扱うものがあっても $VERSION が数値でないという警告が出なくなります。

(たとえ 1 文字の文書パッチでも)バージョン番号を増やすことなく何かを リリースしてはいけません。 1 文字の文書パッチであっても副マイナー番号を変更するべきです。

依存

モジュール作者は、他のモジュールに依存するかどうか、どのモジュールに 依存するかについて注意深く考慮するべきです。

もっとも重要なこととして、できるだけ安定しているモジュールを選んでください。 優先順位としては:

Makefile.PL か Build.PL の pre-requisites に、他の Perl モジュールの 必要バージョンを指定します。

Makefile.PL や Build.PL と、require 5.6.1 のような形の両方で、 Perl の必要バージョンを指定します。 詳しくは "require" in perlfuncuse VERSION の節を参照してください。

テスト

全てのモジュールは配布する前に ("make disttest" を使って) テストされるべきですし、テストはモジュールをインストールしようとしている 人々によっても ("make test" を使って) 実行可能であるべきです。 Module::Build の場合は make test の等価物である perl Build test を 使います。

これらのテストの重要性はモジュールの安定性に比例します。 安定していると表明したり、広く使われることを望むモジュールは、できるだけ 厳密なテスト体制に固執するべきです。

(開発プロセスや時間に与える影響を最小限にするように) テストを書くのを助ける モジュールには Test::Simple, Carp::Assert, Test::Inline などがあります。 さらに洗練されたテストスイートは Test::More と Test::MockObject です。

パッケージング

モジュールは標準的なパッケージングツールの一つを使って パッケージ化するべきです。 現在のところ、ExtUtils::MakeMaker および、よりプラットフォーム独立で、 一貫した方法でモジュールをインストールできる Module::Build という選択肢が あります。 ExtUtils::MakeMaker を使うときは、パッケージを作るには "make dist" を 使います。 MakeMaker 風のスタイルでモジュールをビルドするのを助けるツールがあります。 これらには ExtUtils::ModuleMaker や h2xs などがあります。 perlnewmod も参照してください。

ライセンス

モジュールにはライセンスを付け、(そのライセンスが一般的なもので、 そのライセンスがライセンスの全文を配布物に含めることを要求していないのでない 限り)、その全文を配布に含めるようにしてください。

もしどのライセンスを使えばいいかわからない場合は、GPL と Artistic licenses のデュアルライセンス (Perl 自身と同じ) にするというのが いい考えです。 perlgplperlartistic を参照してください。

よくある落とし穴

車輪の再発明

CPAN によって提供されている、すでにとてもとてもうまくいっている アプリケーション分野もあります。 例としてはテンプレートシステムや日付と時間のためのモジュールであり、 その他にもたくさんあります。 これらのものの自分専用版を書くというのは通過儀礼ではありますが、 あなたがそれを公開することを Perl の世界が本当に必要としているかどうかを 慎重に検討してください。

やりすぎ

あなたのモジュールは開発者のツールキットの一部です。 ツールキット 全体 ではありません。 これはあなたのコードをモジュール化された建築ブロックではなく一枚岩のシステムに なるまで余分な機能を追加しようとする誘惑です。

不適切な文書

間違った読者に向けて書くという罠に陥らないでください。 主な読者は、少なくともモジュールの適用分野についてある程度の理解のある 適度に経験を積んだ開発者で、単にモジュールをダウンロードして、できるだけ 早く使い始めたいと思っている人々です。

チュートリアル、エンドユーザー向け文書、研究論文、FAQ などはモジュールの 主文書としては不適切です。 どうしてもこれらのものを書きたいなら、My::Module::TutorialMy::Module::FAQ のような副文書として含めて、主文書の SEE ALSO 節に リンクをつけてください。

SEE ALSO

perlstyle

一般的な Perl スタイルガイド

perlnewmod

新しいモジュールの作り方

perlpod

POD 文書

podchecker

POD の正しさを検証する

パッケージングツール

ExtUtils::MakeMaker, Module::Build

テストツール

Test::Simple, Test::Inline, Carp::Assert, Test::More, Test::MockObject

http://pause.perl.org/

Perl Authors Upload Server。 モジュール作者のための情報へのリンクがあります。

ソフトウェア工学に関する良い本はなんでも

AUTHOR

Kirrily "Skud" Robert <skud@cpan.org>