红宝石哈希树与块

ale*_*lex 1 ruby tree dsl block

我怎样才能做到这一点:

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
Run Code Online (Sandbox Code Playgroud)

并产生以下:

MyClass.build #=>{:title=>'some title',:collection=>{:node1=>'node1',:node2=>'node2',:another_collection=>{:node1=>'node1',:node2=>'node2'}},:end_node=>'some text'}
Run Code Online (Sandbox Code Playgroud)

我正在尝试的是制作简单的DSL并构建哈希树.我确信可以使用method_missing和instance_eval完成,但我现在不知道如何构建该逻辑.

感谢帮助

Mla*_*vić 8

在你的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}}
Run Code Online (Sandbox Code Playgroud)