Praggerプラグインの作成方法について説明します.

単純なプラグイン

プラグインはrubyプログラムです.プラグイン名.rbというファイル名でプラグインを記述し,適当なディレクトリに保存します.それでは,入力に含まれるPlaggerというテキストをPraggerに置換するプラグインを作成してみましょう.

次のようなプログラムを記述して,private_plugin/sample_plugin.rbとして保存します.

def sample_plugin(config, data)
  data.collect {|x| x.to_s.gsub(/Plagger/, 'Pragger') }
end

プラグイン名と同じ名前のメソッドが,プラグインを実行した場合に呼び出されます.それ以外には,いかなる制約もありません.クラスを定義してもかまいませんし自由にメソッドを定義してもかまいません.

このプラグインを使ってみましょう.config.yamlに次のように書きます.

- module: stdin
- module: sample_plugin
- module: stdout

stdinプラグインによって標準入力を読みとり,sample_pluginプラグインによってPlaggerをPraggerに置換したあとで,stdoutプラグインによって標準出力に出力します.さて実行してみましょう.

$ ./pragger -p private_plugin

例えば「それPlaggerでできるよ」と入力してCtrl-D(WindowsだとCtrl-Z + Enter)を入力すると,「それPraggerでできるよ」と表示されるはずです.

簡単ですね!

もうちょっと詳しく

sample_plugin.rbに定義したsample_pluginメソッドは,引数を二つとります.configdataです.

configにはconfig.yamlに設定したconfig:以下をRubyプログラムとして解釈したものが渡されます.例えばconfig.yamlに次のように書いてみます.

- module: sample_plugin
  config:
    abc: abcdefg
    xyz:
      - 1
      - 2
      - 3

この場合は,configは次のようなRubyのハッシュになります.

{ "abc" => "abcdefg"; "xyz" => [1, 2, 3] }

プラグインに設定項目が必要な場合は,ここに書いてプラグインに渡します.ちなみにconfig:config.yamlに記述されていなかった場合は(最初の例とか),confignilになります.

dataは「プラグインが処理するデータ」です.またメソッドの返り値が「プラグインが処理した後のデータ」になります.このdataは「Arrayクラスのインスタンス」です.Plaggerではこのプラグインが処理するデータはRSS Feedと決まっているようですが,Praggerでは配列の要素がなにかということはわかりません(プラグインによってどのようにも変化します).

プラグインのメタ情報について

どういった設定項目が必要か,だれが作ったプラグインか,といった情報を表現する統一的な方法は,現時点では定義されていません. 一応,プラグインの説明として,##で始まるコメントを書いておくと,./pragger -u plugin_nameとしたときに表示されるようになっています.

これは今後変更される可能性があります(というかsoutaroとしては変更したいと思っています).

注意

requireをどこに書くべきか

プラグインが依存するライブラリはrequireによってロードします.requireは,メソッドの外側,つまり普通にRubyプログラムを書く場合と同じ場所に書いてかまいません(最近変更になりました).requireに失敗した場合は,そのプラグインはロードされません. 今後は推奨されるrequireのスタイルとしては「一番外側に書く」となります.その方が,依存ライブラリが無くて実行できないプラグインをロードすることがなくなりますからね.(./pragger -lとして,利用できるプラグインのリストを確認することができます)

プラグインはstate lessに

プラグインが状態を持つ場合に,意図と異なる動作をする可能性があります.プラグインはPluginクラスのオブジェクトとして,それぞれのプラグインについて一つずつインスタンスが作成されます(プラグインのメソッドは,そのオブジェクトの特異メソッドとして定義されます).

他のプラグインを使う場合

あるプラグインから他のプラグインを使う場合にはeval_praggerメソッドを使います.

つぎのプラグインは,save_rssプラグインに入力をそのまま引き渡すものです.

def save_rss2(config, data)
  eval_pragger([{"module" => "save_rss", "config" => config}], data)
end

eval_praggerメソッドは,入力としてハッシュの配列と,配列を受け取ります.

プラグイン名

プラグイン名は,プラグインの存在するパスのパス区切りを::に置き換えたものです.例えば,private_plugin/hoge.rbというプラグインの名前は./pragger -p private_pluginとした場合にはhogeになります.あるいはprivate_plugin/Publish/your_plugin.rbというプラグインの名前は./pragger -p private_pluginとした場合にはPublish::your_pluginとなります.

もし他の人が作ったプラグインと名前が衝突してしまった場合は,プラグインを保存するディレクトリを深く掘ってみてください.barというプラグインが二つあった場合は,片方をYour_plugin/bar.rbとして保存し,もう片方をMy_plugin/bar.rbとして保存することによって,Your_plugin::barMy_plugin::barとして区別することができます.

Praggerは,同名のプラグインが二つあった場合には,あとからロードしたプラグインのほうを優先します.プラグインをロードする順番は

  1. 標準のプラグイン
  2. -pオプションで指定されたディレクトリに含まれるプラグイン
  3. -pオプションが複数あった場合には,前のほうに指定されたディレクトリのプラグインから順

です.

--soutaro

プラグインの投稿

プラグインをBlog等で公開する時に、同時に「本家統合希望」と書いていただければ、PraggerのSubversionに取り込まさせていただきます。 取り込まさせて頂いたプラグインは、Praggerと同じライセンスで配布させて頂きます。

また、コミッターになりたい人は、チャットルームなどで、話しかけていただければと思います。