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

第2回 attributeを使ってplugin作成を支援する

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

今回のテーマ

今回は,Perlのattributeという仕組みの詳細と,そのattributeを利用したClass::Componentのpluginについての解説,pluginの作成方法といった話題を取り上げます。

サンプルアプリケーション

本連載では,プラガブルなモジュールを作製するという事を考えて,Gopperという実際に実行可能なサンプルアプリケーションを元に解説を行ないます。GopperはCodeRepos上のsvnリポジトリに置いてあるので各自checkoutしてください。

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

attributeとは

attributeとは,Perlのサブルーチンや変数に属性を定義して,サブルーチンとしての挙動を標準から変更したり,どのようなサブルーチンなのかを定義付けする事が出来ます。

たとえばCatalystを利用してControllerを書くときには

sub auto : Private {
    my ( $self, $c ) = @_;

    ...

    }
/code>

などと書きますよね。この例ではPrivateの部分がattributeになります。

この説明だけでは,なかなかピンとこないので実例を混ぜつつattributeについて解説します。

Perl標準で利用できるattribute

たとえば標準ではlvalueという属性が利用できます。

package Jitensya;
use strict;
use warnings;

sub new { bless { sound => 'リンリン' }, shift }

sub sound : lvalue {
    shift->{sound};
}
1;

package main;
use strict;
use warnings;

my $mama = Jitensya->new;
print $mama->sound; # 「リンリン」と出力

$mama->sound = 'チリンチリン';
print $mama->sound; # 「チリンチリン」と出力


と記述でき,サブルーチンやメソッドを左辺値として扱うことが出来ます。

標準で利用できるattributeはlvalueの他に,thread処理で利用するmethod/locked/sharedと,ourで利用するunique(perldoc -f our)があります。

ただ,これだけではCatalystで利用するようなattributeは逆立ちしたって使えません。 どうするかというと,Package-specific Attribute Handling(package固有に属性をハンドリングさせる)という機能を利用します。

Package-specific Attribute Handling

自作モジュール中に独自のattributeを実装する事もできます。普通の状態では,先述の標準で組み込まれたattributes以外のattributeを指定するとエラーが発生してしまいます。

#example.pl
use strict;
use warnings;

sub foo : bar {
}
$ perl ./example.pl 
Invalid CODE attribute: bar at ./example.pl line 4
BEGIN failed--compilation aborted at ./example.pl line 5.

ではどうするのかというと,attributeを利用したいパッケージ内にてMODIFY_CODE_ATTRIBUTESというサブルーチンを定義する事により,独自のattributeを利用出来るようになります。

#example2.pl
use strict;
use warnings;

print "script start\n";

sub MODIFY_CODE_ATTRIBUTES {
    my ($pkg, $ref, @attrs) = @_;
    print "MODIFY_CODE_ATTRIBUTES: set up\n";
    print "MODIFY_CODE_ATTRIBUTES: attrs: $_\n" for @attrs;
    return;

}

sub test : catalyst sledge(miyagawa) soozy(yappo) boofy {
    print "test: start\n";
}

test;
$ perl ./example2.pl 
MODIFY_CODE_ATTRIBUTES: set up
MODIFY_CODE_ATTRIBUTES: attrs: catalyst
MODIFY_CODE_ATTRIBUTES: attrs: sledge(miyagawa)
MODIFY_CODE_ATTRIBUTES: attrs: soozy(yappo)
MODIFY_CODE_ATTRIBUTES: attrs: boofy
script start
test: start

このような形でattributeを活用する事が出来ます。

更に詳細の話は,次回に行う予定です。

余談になりますが,perldoc attributes の中の Package-specific Attribute Handlingに関するドキュメントには

WARNING: the mechanisms described here are still experimental.  Do not rely on the current implementation.  In particular, there
       is no provision for applying package attributes to ’cloned’ copies of subroutines used as closures.  (See "Making References" in
       perlref for information on closures.) Package-specific attribute handling may change incompatibly in a future release.


と記載されており,パッケージ独自のattributeに関しては,実験的な実装だと強調されています。しかし, Catalyst や DBIx::Class などで多数のユーザーに利用されてしまっている機能なので,きっと気にしなくても大丈夫です(多分)。

著者プロフィール

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

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

URLhttp://blog.yappo.jp/

コメント

コメントの記入