概要
ユーザーが拡張可能なライブラリを作成する
詳細
ユーザーが拡張可能なライブラリを作成します。
※ライブラリ作成者側の視点の話
ライブラリの特定の処理に、色んなパターンがあったとします。
例えばhtmlのタグを出力する機能なら、div/span/body・・・・など。
ここで、ライブラリ側がdiv/spanしか用意しておらず、
ユーザーがpタグを利用したい場合に、拡張可能な形式にしておくと便利です。
Rubyはダックタイピングなので、特定のメソッドがあることのみ想定しておけばよいです。
後はそのメソッドを実装したクラスをユーザーにどのように指定させるかを決めます。
色々と方法はあると思いますが、今回はDSLの設定ファイルにクラスを設定させます。
サンプルコード
仕様
ライブラリで、特定のメソッドを持つクラスを想定して処理を記述します。
今回の例ではDSL用に用意したhogeableメソッドにhogeメソッドを実装したクラスを
渡すとユーザー定義のクラスをライブラリ側で実行します。
構成
extensible_library.rb:ライブラリ
calee.rb:ライブラリが読み込むDSLで記述されたファイル(Gemfileなどのような立ち位置)
extended_class1.rb:ユーザーが拡張するクラス1
extended_class2.rb:ユーザーが拡張するクラス2
extensible_library.rb
# encoding: utf-8 class HogeExecutor # DSLで記載されたファイルをパースして実行 def execute src = File.open("calee.rb") {|f|f.read} instance_eval src end # hogeableに指定されたクラスがhogeメソッドを実装していることを前提に処理するDSL用メソッド def hogeable(klass) p klass.new.hoge end end class Hage def hoge "hage" end end HogeExecutor.new.execute
calee.rb
# encoding: utf-8 require "./extended_class1" require "./extended_class2" # ユーザー定義クラス1をDSLに指定する hogeable Hoge # ユーザー定義クラス2をDSLに指定する hogeable Hige # ライブラリが用意しているクラスを利用する hogeable Hage
extended_class1.rb
# encoding: utf-8 # ユーザー側が追加したクラス class Hoge def hoge "hoge" end end
extended_class2.rb
# encoding: utf-8 # ユーザー側が追加したクラス class Hige def hoge "hige" end end
出力
extensible_library.rbを実行
"hoge" "hige" "hage"