プラグインローダー
プラグインローダーを試作しました。
方針
プラグインロードの流れ
ということで、プラグインローダーでは以下のロジックでプラグインを検出しロードします。
- rubyのロードパス($LOAD_PATH)、およびインストールされている最新のgemのロードパス以下を探索し、
- "jiji_plugin.rb"を検出・ロード。
- "jiji_plugin.rb"内では、jijiのAPIを実行することで機能をjijiに登録します。
RubyGemsのプラグインの仕組みと似ていますが、「旧バージョンのgemのプラグインもロードされる」といろいろ問題が起きそうなので「最新のGemに含まれるプラグインのみロードする」仕組みにします。
実装
以下のとおり。
require 'rubygems' module JIJI module Plugin @@registry = {} #プラグインを登録する。 #future:: 機能の識別子 #instance:: 機能を提供するプラグインインスタンス def self.register( future, instance ) if @@registry.key? future @@registry[future] << instance else @@registry[future] = [instance] end end #プラグインを取得する。 #future:: 機能の識別子 #return:: 機能を提供するプラグインの配列 def self.get( future ) @@registry.key?(future) ? @@registry[future] : [] end # プラグインローダー class Loader # プラグインをロードする。 def load ($: + Gem.latest_load_paths).each {|dir| plugin = "#{dir}/jiji_plugin.rb" next unless File.exist? plugin begin Kernel.load plugin server_logger.info( "plugin loaded. plugin_path=(#{plugin})" ) rescue Exception server_logger.error( "plugin load failed. plugin_path=(#{plugin})" ) server_logger.error($!) end } end attr :server_logger, true end end end
以下のような内容の"jiji_plugin.rb"を含む適当なgemを作って、
JIJI::Plugin.register( :test, "aaa" )
「gem install」しておけば、「JIJI::Plugin::Loader#load」時に実行され、「:test」機能を提供するプラグインとして「"aaa"」が登録されます。