Perlでプラガブルモジュールを作ろう!

第1回 Class::Componentから始めるプラガブルモジュール

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

はじめに

はじめまして。大沢と申します。

この連載では,筆者が実装したCPANモジュールのClass::Componentを題材にしつつ,近代的なPerlでのプラガブル(拡張可能)なソフトウェアの実装方法を紹介します。

今回は,Class::Componentの概要を説明します。

本連載で使うサンプルアプリケーション

本連載では,プラガブルなモジュールを作製するという事を考えて,Gopperというサンプルアプリケーションを元に解説を行ないます。

GopperはCodeRepos上のsvnリポジトリに置いてあるので各自checkoutしてください。

svn co -r 271 http://svn.coderepos.org/share/lang/perl/Gopper/trunk Gopper

サンプルアプリケーションは連載中にも頻繁にupdateされる事が予想されますので,毎回リビジョン付きのsvnコマンド行を明記するようにします。

なお,Gopperを使ったサンプルは次回の連載から取りあげます。

Gopper

Gopperとは,最近再評価され始めているGopherプロトコルのサーバ実装を,Plaggerのようなプラガブルアプリケーションとして,筆者がClass::Componentを用いて実装したGopherサーバです。

サーバの各フェーズにフックポイントがあり,Apacheのモジュールを作製するノリでプラグインを実装することが出来ます。

現在はシンプルな機能しか持ち合わせていませんが,プラグインを実装することによりGopher上でCatalystSledgeなどといったWeb Frameworkを利用できたり,HTTPなどのGopher以外のプロトコルに対応する事が可能になります。

Class::Componentとは

Class::Componentとは,Perlモジュールでプラグイン機能を登載する時に必要な処理を全て引き受けてくれるモジュールです。

Class::Accessor::Fastなどのアクセサモジュールのプラガブル版だと思っていただければ間違いありません。

例えばMyClassというモジュールでプラグイン機能を使いたくなった場合には,

package MyClass;
use strict;
use warnings;
use Class::Component;
1;

とClass::Componentをuseして下さい。Class::Componentをロードする時に別途パラメータを付加する必要が無ければuse baseでも問題ありませんが,useするだけでもClass::Componentが継承ツリーに入り,機能を利用することが出来ます。

特長

Class::Componentの特長としては以下のような特徴があります。

  • Component追加で基本メソッドを拡張出来る
  • Plugin追加で,フックポイントへのフック処理追加や,Pluginメソッドを追加出来る
  • Pluginで追加するメソッドの実装方式(普通にメソッド生やす,AUTOLOAD,SingletonMethod)を選べ,選ばなければメソッド生えない
  • Plaggerのようなconfigを利用するPluginを簡単に実装できる
  • モジュール独自にAttribute処理を追加出来る
  • Class::Componentを利用したモジュールを,さらに別モジュールが継承する事が出来る
  • Class::Componentを使ったオブジェクトをYAML::DumpしてYAMLに変換した後でも,そのYAMLをYAML::Loadすれば普通に動くので,オブジェクトの永続化を取り易い

他にも特長がありますが,混み入った話になってくるので連載を通じて紹介しようと思います。

主要コンポーネント

Class::Componentは,主に3種類のコンポーネントから構成されており,それぞれComponent,Attribute,Pluginと名付けられています。

Component

作成したモジュールの基本的な動作をカスタマイズするコンポーネントになっています。

大まかな挙動としては,CatalystのPluginと似ていて,単純にモジュールの@ISAにComponentのpackageを追加して継承ツリーを太らせます。

作成するモジュールにとって,プラガブルではない拡張を施したい場合にはComponentを使って拡張を行ないます。

MyClassモジュールに対する名前空間はMyClass::Component::*になります。

Attribute

Pluginで利用するAttributeを定義するコンポーネントとなっています。

MyClassモジュールに対する名前空間はMyClass::Attribute::*となっており,MyClass::Attribute::SimpleといったAttributeを作成した場合には

package MyClass::Plugin::Foo;
use strict;
use warnings;
use base 'Class::Component::Plugin';

sub plugin_method: Simple {
    my($plugin, $context, $args) = @_;
    ...
}

1;

といった形で利用する事が出来ます。

Plugin

いわゆるプラグインで,Class::Componentを利用したモジュールの要となるコンポーネントです。

Componentと違い,プラグイン固有にインスタンスを持ち,設定もそれぞれ固有に持っています。

先ほど説明したAttributeをメソッドに対して利用する事により,モジュールを幅広くカスタマイズするプラグインを作成できます。

著者プロフィール

大沢和宏(おおさわかずひろ)

趣味で携帯検索サイト iYappoを運営つつコード書きやネタサイトを作る毎日。最近はCodeReposを立ち上げた。執筆活動は,前世紀にThe BASICへ寄稿したのを皮切りに,携帯雑誌のコラム書きや技術誌へ思い出したように執筆している。

URLhttp://blog.yappo.jp/

コメント

コメントの記入