前回の
CPANモジュールの作成
それでは、
モジュールの命名規則
まずはモジュールの名前を決めましょう。CPANの世界では、Text::Markdownというように
Perlの世界はご存じのとおりTMTOWTDI
CPANモジュールにはAcme::という階層があります。ここはジョークモジュール用の階層で、Acme::Songmuというモジュールを作りながら、
モジュールのひな型を作成する
minil newサブコマンドを使って、
% minil new Acme::Songmu
Writing lib/Acme/Songmu.pm
(省略)
[Acme-Songmu] $ git add .
Finished to create Acme::Songmuいろいろ出力されましたが、Acme-Songmuが作られ、git addまで実行されました。
MinillaではGitによる管理が必須
Minillaを使ったモジュール開発では、
リモートリポジトリはGitHubを利用するのがお勧めです。あとで説明するREADME.へのステータスバッジの表示設定など、Acme-Songmuであれば、git remote add origin git@github.といった具合です。
試しにテストを実行する
minil newで作られたプロジェクトディレクトリに移動して、minil testを実行してみましょう。minil testはモジュールのテストスイートを実行するコマンドです。
$ minil test
(省略)
t/00_compile.t .. ok
All tests successful.
Files=1, Tests=1, 0 wallclock secs ( 0.02 usr 0.01 sys +
0.07 cusr 0.02 csys = 0.12 CPU)
Result: PASSモジュールのビルドとテストが実行され、
モジュールのディレクトリ構成を理解する
さっそく開発を進めたいところですが、
minil newが生成したファイルをもとにCPANモジュールのディレクトリ構成を理解していきましょう。初期ファイルは次のように分類できます。
- ライセンスファイル
- LICENSE
(ライセンスファイル)
- LICENSE
- 設定ファイル
- minil.
toml (Minillaの設定ファイル)
- minil.
- 開発時に編集するファイル
- lib/
Acme/ Songmu. pm (メインのモジュールファイル) - t/
00_ compile. t (最低限のテストファイル) - cpanfile
(依存モジュールを記述するファイル) - Changes
(変更履歴を記述するファイル)
- lib/
- Minillaが自動的に更新するファイル
- Build.
PL (モジュールビルドのためのファイル) - META.
json (モジュールのメタ情報が記述されたファイル) - README.
md (ドキュメントファイル)
- Build.
順に見ていきましょう。初期生成はされない各種配置用ディレクトリについても説明します。
ライセンスファイル
LICENSEファイルには、
設定ファイル
minil.はMinillaの設定ファイルです。その名のとおり、
開発時に編集するファイル
lib/がメインのモジュールファイルです。ほかにモジュールファイルを追加したい場合は、libディレクトリ以下に追加できます。
t/は最低限のテストファイルです。今後テストファイルはtディレクトリ以下に配置します。
cpanfileは依存モジュールを記述するためのファイルです。のちほど詳しく説明します。
Changesはモジュールの更新履歴を記述するためのファイルです。
Minillaが自動的に更新するファイル
Build.、META.、README.は、
README.を編集できないことは奇妙に思えるかもしれませんが、README.を自動生成するためです。こちらに関しても後述します。
コマンドラインツール配置用ディレクトリ
Perlはコマンドラインツールを簡単に作れる言語でもあるため、miniコマンドがまさしくそれです。そういった場合、scriptディレクトリを作成し、
逆に、scriptディレクトリに配置するのは危険です。そのような作者のためのファイルはauthorディレクトリに配置することが規約となっています。
サンプルコード配置用ディレクトリ
サンプルコードを同梱したい場合は、examplesかegのどちらかに配置することが推奨されています。使い分けは好みの問題ですが、egを使うことが多いです。
コード以外のファイルを配置するディレクトリ
ソースコード以外のファイルをモジュールに同梱したい場合があります。たとえば、shareディレクトリに配置します。
その場合、File::Shareなどのモジュールを通してアクセスして開発する必要があります。
モジュールを開発する
それでは、libディレクトリ以下にモジュールファイルを、tディレクトリ以下にテストファイルを配置して開発していきます。
CPANモジュール開発ならではの要件として、xtディレクトリにテストファイルを配置することが慣例となっています。
ドキュメントを書く
ドキュメントは、Acme::Songmuの場合はlib/がメインのモジュールファイルです。
このPodが、README.を自動生成するしくみとなっているので、
Podの書き方は、perldoc perlpodで調べられます。最初は書き慣れないかもしれませんが、
NAMEとDESCRIPTIONは単語のとおりモジュールの名前と説明です。特徴的なのはSYNOPSISで、
スペルチェックに対応する
Minillaは、
単純なスペルミスは修正すればよいですが、
- 除外単語をPod冒頭のstopwordsリージョンに記述する
- Pod上のコード片はcode text記法のC<>やC<<>>できちんと囲む
以下は、Acme::Songmuのソースコード内から抜粋したものです。
=encoding utf-8
=for stopwords sandboxing
=head1 NAME=item C<< $songmu->gmu >>README.mdにステータスバッジを表示する
README.には、
MinillaはREADME.をPodから自動生成するため、README.を直接編集してバッジ画像表示のリンクを書き足すのは好ましくありません。その代わり、
たとえばTravis CIであれば、minil.に次の記述を追記することで実現できます。ほかにも多くのサービスに対応しています。詳しくは、
badges = ["travis"]Perlのプロジェクトを各種CIサービスと連携させる方法については、
モジュールのバージョンを記述する
メインモジュールファイル上のグローバル変数$VERSIONでバージョンを記述します。これがCPANモジュール自体のバージョンになります。Minillaの標準のひな型では、
our $VERSION = "0.01";モジュールをまだ一部環境でサポートが残っている古いPerl 5.
use version 0.77; our $VERSION = version->declare("v0.0.1");これは必ず1行で書かないといけません。少し冗長ですが、v.の部分)
依存モジュールの記述と動作確認
CPANモジュールのインストールが失敗する主要な原因の一つに、
しかし、cpanfileがデファクトスタンダードになり、
cpanfileについて詳しくは、perldoc cpanfileもしくは、
scan-prereqs-cpanfileで簡単に依存を抽出する
cpanfileは手で記述するのではなくソースコードから機械的に自動生成し、scan-prereqs-cpanfileコマンドに自動生成させるのが簡単です。このコマンドは、
% cpanm -n App::scan_prereqs_cpanfilescan-prereqs-cpanfileコマンドを次のように実行します。ソースコード内のuse文などを静的に解析して依存モジュールを自動的に抽出し、cpanfileに書き出されます。
% scan-prereqs-cpanfile --scan-test-requires > cpanfile書き出された内容を確認し、
use文に最低依存バージョンを記述する
新しい機能を使いたい場合など、cpanfile内で明示的にそのバージョンを指定する必要があります。それも、use文に最低依存バージョンを記述することで、scan_に自動的に出力させられます。
たとえば、Class::Accessor::Lite::Lazyのバージョン0.
use Class::Accessor::Lite::Lazy 0.03;このように記述すると、scan-prereqs-cpanfileは次のように最低依存バージョンを含めて依存を書き出してくれます。このように積極的に最低依存バージョンを記述するのはグッドプラクティスです。
requires 'Class::Accessor::Lite::Lazy', '0.03';これはあくまでcpanfileにはバージョン固定のための記法はありますが、
scan-prereqs-cpanfileで抽出できない依存
Module::Loadなどのクラスローダや、scanprereqs-cpanfileでは抽出できません。これらの依存は、
なお、
必要最小限のテスト実行のためにTest::Requiresを活用する
ユーザーがCPANモジュールをインストールする場合、
たとえば、DBD::mysqlが入っているときのみMySQL関連のテストを実行するといったケースです。そういった場合はTest::Requiresというモジュールを使うのがセオリーで、
use Test::Requires 'DBD::mysql';これで、DBD::mysqlがテスト実行環境に入っているときのみ実行されます。
開発者側ではTest::Requiresのテストをスキップしない
前項のTest::Requiresの振る舞いは、Test::Requiresで指定されている依存モジュールを抽出し、cpanfileに記載できると良さそうです。
そのためのscan-prereqs-cpanfileのオプションが、--scan-test-requiresです。たとえば先ほどのuse Test::Requires 'DBD::mysql'が記述されたテストファイルが存在するプロジェクトに対して、scan_を実行すると、
on develop => sub {
requires 'DBD::mysql';
};cpanfileのdevelopセクションは、cpanmでインストールするためには、--withdevelopを指定します。
% cpanm --installdeps --with-develop .モジュール開発者やCI環境では上記のコマンドで依存のインストールを行い、
リリース前確認を行う
これで一通りモジュールの開発が終わりました。リリース前にテストスイートを実行してみましょう。minil test --allを実行すると、
% minil test --all
(省略)
t/00_compile.t ................ ok
t/01_singleton.t .............. ok
t/02_gmu.t .................... ok
xt/minilla/cpan_meta.t ........ ok
xt/minilla/minimum_version.t .. ok
xt/minilla/permissions.t ...... ok
xt/minilla/pod.t .............. ok
xt/minilla/spelling.t ......... ok
All tests successful.
Files=8, Tests=14, 14 wallclock secs ( 0.05 usr 0.03 sys
+ 2.83 cusr 0.53 csys = 3.44 CPU)
Result: PASS標準のテストのほかにxt/というMinillaが生成したモジュール検証用のテストがいくつか実行されています。これらが通れば、
<続きの
本誌最新号をチェック!
WEB+DB PRESS Vol.130
2022年8月24日発売
B5判/
定価1,628円
ISBN978-4-297-13000-8
- 特集1
イミュータブルデータモデルで始める
実践データモデリング
業務の複雑さをシンプルに表現! - 特集2
いまはじめるFlutter
iOS/Android両対応アプリを開発してみよう - 特集3
作って学ぶWeb3
ブロックチェーン、スマートコントラクト、 NFT

