Component Loader
コンポーネントローダーは Ruby で書かれたファイルを読み込み、クラスを UNO コンポーネントとしてインスタンス化するための sigle component factory インスタンスを返す。
Java ではファイル単位、Python でもファイルのモジュールで単位に分かれているため一つのコンポーネントをカプセル化できる。一方で Ruby では読み込んだファイルの内容は全てトップレベルにマージされる。
ローダー内の Ruby インスタンスは一つしかない。どうやって複数のコンポーネント定義を別々に取り扱えばいいのかな・・・?
Ruby と UNO は相性のいいとこが一つもない。
新しいコンポーネントの要求があった場合にローダーは該当するファイルを読み込みそのファイルで新たに定義されたコンポーネントについて知る必要がある。
A.rb
require 'uno.rb' XJobExecutor = Runo.uno_require('com.sun.star.task.XJobExecutor') class A include Runo::Base include XJobExecutor def initialize(ctx) @ctx = ctx end def trigger(event) #... end end module RubyLoader @@imple << [A, 'implementation_name', ['service_name1', '2']] end
コンポーネントはそれぞれ実装名とサポートしているサービス名を提供するのが一般的。実装 ID と実装するタイプ (インターフェース) は Runo::Base から提供するとして、他の二つもクラスから提供されるようにしてもよい?
class UNOComponentBase include Runo::Base @@imple_name = nil @@service_names = nil def UNOComponentBase.imple_name @@imple_name end def ... end class B @@imple_name = 'org.something.Imple' @@service_names = ['name1', 'name2'] def ... end module RubyLoader @@imple << A end
こうするとか・・・。実装名とかサービス名は本来は定数だけど実行時に変更できるクラス変数にするか、クラスの変更できない定数にするかどうするか。