Feb 12, 2009

プラグインでMT::Objectのインタフェースを拡張する

リコメンデーションエンジンを実装するためのフレームワークをMTに組み込もうかと思って、少しだけ手を動かしている。

ogawa - Revision 640: /trunk/Recommendable

でもって気がついたのは、ドキュメントされていないけど、プラグインを使ってMT::Objectのインタフェースを拡張できるということだ。

MT::Entryは、デフォルトでMT::Object、MT::Taggable、MT::Scorableを継承している。3つのスーパークラスは論理的には(ディスパッチ順はあるけれども)等価だが、便宜上MT::EntryはMT::Objectのサブクラスで、MT::TaggableとMT::Scorableというインタフェース(Mixin)を使えるように宣言されていると考えると分かりやすい。

ここでは、プラグインを使って、MT::EntryをMT::Taggable、MT::Scorableインタフェースだけでなく、ユーザ定義のLibbleRabbleインタフェースを持つクラスにすることを考える。

まず、plugins/LibbleRabble/config.yaml(プラグイン本体)を用意する。

name: Libble Rabble
id: LibbleRabble
version: 0.01
object_types:
  entry: LibbleRabble

このように書いておくと、entryを定義しているMT::EntryクラスがLibbleRabbleインタフェースを継承するようになる。内部的にはMT::Entryパッケージの@ISA配列の末尾に"LibbleRabble"という文字列が追加されるだけ、これはPerl Mixinの代表的な実現方法の一つ。

LibbleRabbleクラスも用意しておこう。plugins/LibbleRabble/lib/LibbleRabble.pmというファイルを作って中身は適当に書いておけばいい。

package LibbleRabble;
sub libble { print "<\n" }
sub rabble { print ">\n" }
1;

テストコードはこんな感じに書いておけばおk。

#!/usr/bin/perl
use lib 'lib';
use MT::Bootstrap;
use MT;
use MT::Entry;
my $mt = MT->new;
my $e = MT::Entry->load(2);
if ($e->isa('LibbleRabble')) {
  $e->libble();
  $e->rabble();
}

制限事項は、

  • 一つのプラグインで一つのインタフェースしか追加できないよ。
  • ドキュメントされていない仕様(ユーザ定義の新しいデータモデルを追加するための仕組みを流用しているだけ)なのでいつか使えなくなってもしらないよ。
  • リブルラブルに深い意味はないよ。

About Me

My Photo

つくばで働く研究者

Total Pageviews

Amazon

Copyright 2012 Ogawa::Buzz | Powered by Blogger
Design by Web2feel | Blogger Template by NewBloggerThemes.com