Hatena::ブログ(Diary)

Yet Another Hackadelic

2006-10-10 もう戦士じゃない

Class::C3と継承ツリーの問題について

d:id:amachang:20061010:1160498195の件について。*1


コメントにも思わず書いたけど、継承ツリーがそこまでセンシティブで、併用した場合に問題があるコードが世間に大量にあるとするならば、C3どーなんだろって思ってみたり。


ただ今日びなmixinは継承のorderまで気にしなければならないとなると、

  • 安易な継承出来ない
  • 継承gkbr
  • 継承しない
  • C3使わない

なんてなったりしてw


ただ気づく所が凄い感覚だなー。

Shibuya.pm TechTalk #07出ちゃいます

僭越ながらTalkerとして出ちゃいます。

MogileFSと言う、日本ではまだソースの少ない優れたテクノロジーを紹介予定です。


ちと心して掛からねば。

さらに後押し頂いたtakesakoさん*2に毎度ながら感謝です。


id:amachangと共に本当にお世話になりっぱなしだなぁ。頭が上がらないっす。

miyagawaさんのdebugネタ

id:miyagawaさんのsubtechでの日記について。


ボクはDamian先生の方がなんかしっくりくるなぁ。

でもdumpにYAMLこそなんかしっくり来るかも。


YAMLはHuman ReadableではあるけどHuman Writableじゃないと思うのは僕だけですかねぇ。

しかしSubtechって面白い情報溢れてるなぁ、これサブテク入りたいとか書いたら入れるもんですか?(w

Module::Starterのplugin機構が面白い件について

ちょっとCatalystの設計上、どうしてもやってみたい拡張があって、周辺技術を調べてる最中、Module::Starterのplugin機構が面白い事に気づきました。


Module::Starter->import

というかModule::Starterってimportが定義してあるだけです。w

sub import {
    my $class = shift;
    my @plugins = ((@_ ? @_ : 'Module::Starter::Simple'), $class);
    my $parent;

    no strict 'refs';
    while (my $child = shift @plugins) {
        eval "require $child;"; 
        die "couldn't load plugin $child: $@" if $@;

        push @{"${child}::ISA"}, $parent if $parent;

        if ($child->can("load_plugins") and @plugins) {
            $parent->load_plugins(@plugins);
            last;
        } 
        $parent = $child;
    }
}

呼び出しに関しては、

use Module::Starter qw/
  Module::Starter::Simple
  Module::Starter::Smart
/;

みたいに使う訳ですが。このwhileループ内の処理が面白い。


まず@pluginsですけど、何もしない場合は、

my @plugins = qw/Module::Starter::Simple Module::Starter/;

ってなります。その次のmy $parentの扱いが非常に気になった訳ですが、

plugins指定されたモジュールの中にload_pluginsがいずれも定義されていない場合は、

  1. 最初の$child(Module::Starter::Simple)は$parentが定義されて無いので@ISAに変更なし
  2. load_pluginsのcanチェックはスルー
  3. $parentに$childを代入($parent = 'Module::Starter::Simple')
  4. 次以降の$childには$parentとしてModule::Starter::Simpleがあるので$childの@ISAにpushする。
  5. $parentにModule::Starterを設定

となるのでload_pluginsが見つかるまでは最初に設定したplugin順に子供になっていき、最後にModule::Starterが最も子孫なクラスになる。


仮に途中でload_pluginsメソッドがあればそれに依存した形でpluginの読み込みとなり、

plugin機構自体捻じ曲げる事が出来る。


pluginのコンセプトがModule::Starter::Pluginのpodに書いてあります。


まさに下記の引用部分がそのまんまですね。*3

By default, the given modules are required and arranged in an is-a chain. That is, Module::Starter subclasses the last plugin given, which subclasses the second-to-last, up to the first plugin given, which is the base class. If a plugin provides a load_plugins method, however, the remaining plugins to be loaded are passed to that method, which is responsible for loading the rest of the plugins.
Module::Starter::Plugin

で、このことが示唆している2つのコンセプトとして続けて書いてあるのが、

engine plugins

An engine is a plugin that stands alone, implementing the public create_distro method and all the functionality required to carry out that implementation. The only engine included with Module::Starter is Module::Starter::Simple, and I'm not sure any more will be seen in the wild any time soon.
Engine Plugins

まぁ大体はcreate_distroを始めとしたimplementすべきメソッドを全部用意した物が唯一のEngine pluginになりますよって事ですね。で、代表例はModule::Starter::Simpleです、って事でしょう。


M::S::PBPだとかM::S::SmartってのはベースクラスをM::S::Simpleにしているので、Engine足りえるんでしょうね。

plain old plugins

Other plugins are designed to subclass an engine and alter its behavior, just as a normal subclass alters its parent class's. These plugins may add features to Module::Starter engines, or may just provide general APIs for other plugins to exploit (like Module::Starter::Plugin::Template.)

The template plugin is a simple example of a plugin that alters an engine to accept further plugins. Other plugins like template will probably be written in the near future, and plugins that exploit the API provided by Module::Starter::Plugin::Template will be available on the CPAN.
Plain Old Plugins

他のプラグインってのはengineのサブクラスであり、その挙動を変える物ですよって事ですね。

またさらに別のpluginの為の標準的なAPIを提供する事があって、恐らくこのplugin機構から考えて、先に読まないとダメって事もあるんでしょうね。恐らくそれの代表がModule::Starter::Plugin::Templateって事なんでしょう。*4


にしてもこのplugin機構って、結構この数行にコンセプトが凝縮されてて、私的には非常にPerlっぽぃって思うんですが皆さん如何ですか?(ぇ

Module::Install

Module::Installって最近良く見るんですけど、イマイチその旨みを知らなかったんですが、

WiKicker の Makefile.PL を Module::Install ベースにに書いてありました。


で引用ですけど、

  • 依存モジュールを、それぞれ必須のもの・ビルドのみ時に必要なもの・推奨のものと分けて処理できる
  • Makefile.PL 実行時に、未インストールの依存モジュールを CPAN からインストールできる。
  • 依存モジュールを feature 別にまとめて、ビルド時に未インストールのものをインストールするか対話的に選択できる。
などの機能が使えるようになる。 Module::Installの利点

ってあるそうな。特に未インストールが対話的にインストール出来る機能って見たことあるけどModule::Installの機能とは露知らず。。。CPAN Authorとして恥ずかしいっすね。^^;

Catalyst::Plugin::Alarm

ちょっと面白いPluginを見つけました。

Catalyst::Plugin::Alarmなんですけど、Catalyst中でalarmにハンドラを付けれるみたいな。

Webアプリケーションのパフォーマンスチューニングとして仕込むのはありだなと思いました。


後はマッシュアップとして外部のWeb Serviceを使う際のタイムアウト処理くらいかな、使えるのって。


同時に依存してるSys::SygActionモジュールは汎用的にSygnalにハンドラ定義出来るんで、結構よさげだなと。

*1:この記法、やっと覚えた件についてorz...

*2id:jtakesakoさんの中の人はご本人ではありませんでした。。。

*3:しかしここの和訳難しい。。。

*4:未確認ですからあしからずw