Ruby inheritedとかmethod_addedを使ってみた

satoyamaが2014/09/12 19:14:30に投稿

Ruby inheritedとmethod_addedを利用した簡易内部DSL

inheritedというクラスメソッドを親クラスに定義しておくと、継承されるたびに呼ばれる。
また、method_addedというクラスメソッドはクラスにメソッドが追加される度に呼ばれる。
これらを利用することで、シーケンシャル(シナリオ)な内部DSLが簡単にできる。

module ScenarioPool
  def senario_prefix
     %w( ready start walk run jump stop finish )
  end
  def  senario
    @scenario || []
  end
  def add_scenario( scenario )
     @scenario || = []
     @scenario << senario
   end
   def method_added( scenario )
     unless scenario_prefix.find{|pre| senario.to_s =~/^#{pre}_/}.nil?
         self.add_scenario( scenario )
     end
   end
end

class Base
  def self.inherited( child )
     child.extend ScenarioPool
  end
  def action!
    self.class.scenario.each { |scenario| self.send( scenario ) }
  end
end

class Scenario1 < Base
  def ready_to_run; puts "OK"; end
  def run_to_goal; puts "running!"; end
  def stop_before_goal; puts "find money!"; end
  def finish_race; puts "it's a bottle cap, orz"; end
  def never_call; puts "never call"; end
end

Scenario1.new.action!
# => OK
# => running...
# => find money!
# => it's a bottle cap, orz

作ってみたけど、あまり効果的なDSLな気がしない。