(h)id:naoyaへの返事
(f)Soozy Conference #2 (n)Yappo (m)ko yappo ne jp (b)http://blog.yappo.jp/ (a)5 (1)今日の持ち物 (1)疑似○○ (i)
(i)
(i)
(1)こぼしてしまいました>< (1)概要 (3)naoyaさんがnaoyaグループでClass::Componentに関する質問をしてくれたので、その返事です (3)Class::Componentとはmalaに「てんさい」といわれて浮かれて作ったモジュール (2)プラガブルっぽいモジュールを比較的楽に作る為のベースモジュール (1)いつも通りネタ無しの真面目トークでごめんなさい (1)では、マジレス開始 (s)Class::Component ところで Hook の使いどころがよくわかって ないんだけど、教えて! (これが主目的だったりする) ---- (3)このHookってのはClass::TrigerとかPlaggerのアレみたいなもんですね (3)sub hoge : Hook('hookpoint') {}みたいな感じでhookするポイントと関数設定出来るけど (3)それを呼び出す$obj->run_hook( 'hookpoint' => $args);が単純すぎて使いずらい (3)最近作ったURI::KeywordExtractなんかはrun_hook使わず (s)URI::KeywordExtract::Detector sub detect { my($self, $args) = @_; return unless my $hooks = $self->class_component_hooks->{'detect'}; my @ret; for my $obj (@{ $hooks }) { my($plugin, $method) = ($obj->{plugin}, $obj->{method}); next unless $self->{uri}->host =~ $plugin->stash->{host}; my $data = $plugin->$method($self, $args); next unless $data; $self->detect_fixup($data, $plugin); return { data => $data, plugin => $plugin }; } return; } ---- (2)とかで、独自にhook呼ぶやつ書いてる (3)たぶんhook呼ぶロジックは自分で好きに書いたらいいんじゃね? (3)それか、Class::Component::Component::RunHook::*に色々用意するとか (1)いっこめ終わり (s)Class::Component#2 Class::Component で DisableDynamicPlugin + Autocall::InjectMethod したときでもプラグインインスタンスの $plugin->config からプラグインに対する設定が取れるといいなーと思っています。 ---- (2)DisableDynamicPluginについて一言いっとく (t)DisableDynamicPlugin (l)FCのoverloadが遅いパッチに騙されて (l)どうにかしてC::Cを早くする為に足掻いた (l)コンポーネントなんで、色々犠牲にさせてる (l)から基本的にオススメ出来ない。 (l)未だに実装方法について迷ってる (1)答えとしては (1)たぶん意図通りにconfigとれるよ! (3)日記のコードの断片だと、どこでやりたいのか解りにくいので多分って事 (1)Example1 (s)hatena.pl use strict; use warnings; use Naoya; Naoya->new->bell; ---- (s)Naoya package Naoya; use strict; use warnings; use Class::Component config => { Jitensya => { sound => 'チリンチリン' } }; __PACKAGE__->load_components( qw/ DisableDynamicPlugin Autocall::InjectMethod / ); __PACKAGE__->load_plugins(qw/ Jitensya /); 1; ---- (s)Naoya::Plugin::Jitensya package Naoya::Plugin::Jitensya; use strict; use warnings; use base 'Class::Component::Plugin'; use Perl6::Say; sub bell : Method { my($self, $context, @args) = @_; say $self->config->{sound}; } 1; ---- (1)Example2 (s)hatena.pl use strict; use warnings; use Naoya; Naoya->class_component_reinitialize( config => { Jitensya => { sound => 'チリンチリン' } } ); Naoya->load_plugins(qw/ Jitensya /); Naoya->new->bell; ---- (s)Naoya package Naoya; use strict; use warnings; use Class::Component; __PACKAGE__->load_components( qw/ DisableDynamicPlugin Autocall::InjectMethod / ); 1; ---- (s)Naoya::Plugin::Jitensya さっきと同じ ---- (3)Example1でもExample2でもhatena.plを動かせば「チリンチリン」と音が鳴ります (t)configを渡せる場所 (l)use Class::Component時のパラメータ (l)class_component_reinitializeメソッドのパラメータ (l) (l)これはDisableDynamicPluginあっても動く (3)DisableDynamicPlugin使うときは、load_pluginsする前にconfig渡せばおk (3)たぶんnaoyaさんはnewした時にconfig渡してたのかな? (3)通常時は、new時にpluginsのインスタンスを作るけど (3)DisableDynamicPluginした時はload_pluginsする直後にインスタンス作る (3)だからnew時にconfig渡してるとうまく行かない事になってるんじゃないかな?と (2)ぶっちゃけconfig関連は、もうちょっと推古が必要だけど (1)言及されてない所のTips (1)Class::Component ::Attribute::* (3)ここはCatalystのAttributeと同じで拡張しまくれるよ (s)たとえば。。。 package Class::Component::Attribute::Jkondo; use strict; use warnings; use base 'Class::Component::Attribute'; sub register { my($class, $plugin, $c, $method, $value) = @_; $plugin->config->{sound} = 'わいが近藤や'; } 1; ---- (3)とかやって、さっきのJitensyaクラスを次のように書き換えると (s)Naoya::Plugin::Jitensya package Naoya::Plugin::Jitensya; use strict; use warnings; use base 'Class::Component::Plugin'; use Perl6::Say; sub bell : Method : Jkondo { my($self, $context, @args) = @_; say $self->config->{sound}; } 1; ---- (3)「チリンチリン」が「わいが近藤や」という出力に変化します (3)Pluginのインスタンス作った後にAttributeの処理が入るので、他にも応用出来ます (1)実際問題 (3)C::Cの名前空間にしかAttribute置けないので、使いにくい (3)YourProj::Attribute::*にも置けるように変更しようと思います (1)終わりに (3)そのデッカいフレームワークで使ってるとかはネタだと思ってる。 (i)
(1)ぶっちゃけ、この場でやる内容じゃないな (1)以上