Plaggerのソースコード読む(4)
今回はPluginのロードについて。
まずload_pluginsメソッド(Plagger.pmです)。
$self->load_plugins(@{ $config->{plugins} || [] });
$config->{plugins}の中身は、(2)の変数をDumpしたのを見たらわかると思う。
一応書くと、
'plugins' => [ { 'config' => { 'feed' => [ { 'url' => 'http://d.hatena.ne.jp/tayaya/rss' } ] }, 'module' => 'Subscription::Config' }, ・ ・ ・ [
こんな感じで、各Pluginの設定が入ってる。
ちなみにGlobalな設定は$self->conf (Plugin側からは$context->conf) でアクセスできます。
load_pluginsの中を見てみると、
my $plugin_path = $self->conf->{plugin_path} || []; $plugin_path = [ $plugin_path ] unless ref $plugin_path;
Globalのplugin_path(外部Pluginのパス)をとってくる。
配列になってるとこからわかるように、plugin_pathは複数設定できるということですね。
次。
for my $path (@$plugin_path) { ・ ・ ・
このforループでは、plugin_pathで設定したディレクトリ内に
PlaggerのPluginファイルがあるかどうかを調べ、
Pluginファイルがあれば$self->plugins_pathに($self->conf->plugin_pathじゃないですよ)
そのパスを設定、ということをやっています。
ここでは
File::SpecやFile::Find::Ruleモジュール、ファイルテスト演算子など、
パスやファイルの扱い方に関して結構勉強になると思うので、
興味のある方はみてみると良いかもしれません。
外部Pluginのパスを設定し終わったら、いよいよconfig.yamlに書いたPluginをロードしていきます。
for my $plugin (@plugins) { $self->load_plugin($plugin) unless $plugin->{disable}; }
@pluginsはload_pluginsを呼ぶときに渡された @{$config->plugins} です。
ではload_pluginの中身。
my $module = delete $config->{module}; $module =~ s/^Plagger::Plugin:://; $module = "Plagger::Plugin::$module";
$moduleに「Plagger::Plugin::*」と、正式名称(?)を代入しています。
$module =~ s/^Plagger::Plugin:://; がなぜ書いてあるかよくわからないのですが、
昔はconfig.yamlには
- module: Plagger::Plugin::Subscription::Config
みたいに書くようにしてたのかな?(古いconfig.yamlと互換性もたせるため?)
とりあえず続き。
if ($module->isa('Plagger::Plugin')) { $self->log(debug => "$module is loaded elsewhere ... maybe .t script?"); } elsif (my $path = $self->plugins_path->{$module}) { eval { require $path } or die $@; } else { $module->require or die $@; }
ここがPluginをロードしてる所です。
まず、
if ($module->isa('Plagger::Plugin')) {
Pluginがすでにロードされているかどうかを調べ、
ロードされていなければ
} elsif (my $path = $self->plugins_path->{$module}) { eval { require $path } or die $@;
外部Pluginのpathをrequire。
どちらでもなければ
$module->require or die $@;
普通にrequireします。
とまあさらっと書いたんですが、
2番目のrequire $pathの部分。
$pathには 'C:\plugin\Sample.pm' みたいにパスが入ってます。
ということは下のようになるわけで、
require 'C:\plugin\Sample.pm';
こんな風にパスでもrequireできるんですね。
初めて知りました。へえー。
最後です。
my $plugin = $module->new($config); $plugin->cache( Plagger::CacheProxy->new($plugin, $self->cache) ); $plugin->register($self); push @{$self->{plugins}}, $plugin;
Pluginをnewし、
cache、registerを呼び出します。
そして
@{$self->{plugins}}にpushして終了です。
registerは重要なので、次回にでも書いていきたいと思います。