рубиновое хеш-дерево с блоками - PullRequest
1 голос
/ 29 июля 2011

как я могу это сделать:

class MyClass

   tile 'some title'

   collection do
    node1 'node1'
    node2 'node2'

      another_collection do
        node1 'node1'
        node2 'node2' 
      end
   end
   end_node 'some text'

end

и производим следующее:

MyClass.build #=>{:title=>'some title',:collection=>{:node1=>'node1',:node2=>'node2',:another_collection=>{:node1=>'node1',:node2=>'node2'}},:end_node=>'some text'}

Я пытался создать простой DSL и построить хеш-дерево. Я уверен, что это можно сделать с помощью method_missing и instance_eval, но я не знаю, как построить эту логику.

Спасибо за помощь

1 Ответ

8 голосов
/ 29 июля 2011

В вашем method_missing вы должны проверить, задан ли блок, и, если это так, рекурсивно вызвать метод main с ним:

class HashBuilder

  def self.build &block
    hb = HashBuilder.new
    hb.instance_eval(&block)
    hb.hash
  end

  attr_reader :hash

  def initialize
    @hash = {}
  end

  def method_missing meth, *args, &block
    @hash[meth] = block ? HashBuilder.build(&block) : args.first
  end
end

p HashBuilder.build{
  a :b
  c :d
  e do
    f :g
  end
}
#=> {:a=>:b, :c=>:d, :e=>{:f=>:g}}
...