2011-07-29 209 views
0

我怎么可以这样做:红宝石哈希树块

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

你尝试过这么远吗?首先,尝试仅处理一级方法调用,即首先使用无块的封面使用。 –

+0

Mladen,谢谢你的回答。创建第一个节点和块是很简单的。只是在method_missing合并散列与方法名称...问题是创建深嵌套树节点... – alex

回答

7

在你method_missing,你应该检查是否有块,并给出了,如果是这样,递归调用的主要方法吧:

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}} 
+1

谢谢男人。你真的帮我... – alex

+1

真棒回答 - 谢谢! –

+1

非常酷!没想到答案如此之短。 –