Railsのプラグイン入門

【ma2注】以下のURLのエントリの翻訳です。この記事が書かれた後にプラグインは正式な機能として Rails に取り込まれました。
http://www.jamis.jamisbuck.org/articles/2005/10/11/plugging-into-rails

ActiveRecord に追加したい新しい acts_as_chunky_bacon ミックスインがあるのに,悪名高きコアチームが却下して,あなたをつまらないやつと呼んだとしよう。他に何ができるだろうか? 人々はこのミックスインを必要としている。Ruby の世界では物事は chunky bacon のように振舞うべきだと,あなたは理解している。

かつて(2005 RubyConf 以前の暗黒時代)あなたに唯一できることは,コードをパッケージして,人々にそのミックスインをどこかに配置してロードパスに加えてrequireしてくれと言うことだけだった。

もう大丈夫! 今や Edge RailsRailsの最新版)は "シンプルかつ効率的" なプラグインシステムを持っている。あなたは作者として1つの zip ファイルを提供して,vendor/plugins ディレクトリに展開するように言うだけでいい。これ以外の設定は必要ない。

作者として必要なことは,以下のようなディレクトリ構造でプロジェクトを作ること。

acts_as_chunky_bacon/
acts_as_chunky_bacon/init.rb
acts_as_chunky_bacon/lib
acts_as_chunky_bacon/lib/acts_as_chunky_bacon.rb

アプリケーションが起動すると,lib ディレクトリは自動的にロードパスに追加され,init.rb が自動的に読み込まれる(どちらも省略可)。この init.rb は,以下のようなことを行う。

ActiveRecord::Base.send :include, ActsAsChunkyBacon

これは何を意味しているのか? これはあなたのプラグインの利用者があなたのプロジェクトを単に vendor/plugins ディレクトリに置き,モデルに対して以下のようにすればいいことを意味している。

  class PoignantGuide < ActiveRecord::Base
    acts_as_chunky_bacon :from => "chapter 3" 
    ...
  end

現状,37signalsではこのプラグインシステムをさまざまなアプリケーションでコードを共有するために利用している。例えばエラー時のEメール通知,共通のbefore_filter,あるいはBackpack と Basecamp を Whiteboard に統合する Web サービスインフラなどに使っている。

私は本当にこのプラグインシステムを気に入っている。これはおそらく完璧ではないだろうが(もっといいやり方がいずれ見つかると思う),コード共有を本当に楽にしてくれる。うまくいけば Rails のコアチームがたくさんの新しい提案に対して「ダメ」と言うのも簡単になる。なぜならそうした機能の多くはサードパーティのアドインとして追加できるようになるからだ。