2011-06-28 49 views
2

我正在研究一個相當簡單的DSL,並希望更自然地聲明和分配變量。如何創建自然變量分配

GlobalMemory.init { 
    val1 5 
    val2 "some string" 
} 

這是一個運行DSL一個簡單的虛擬機。這適用於此代碼很好

class GlobalMemory 
    include Singleton 

    def self.init &blk 
    GlobalMemory.instance.allocate &blk 
    end 

    def method_missing sym,*args, &blk 
    @segments[sym]=args[0] 
    end 

    def allocate &blk 
    self.instance_eval &blk 
    end 
end 

有沒有辦法允許val1=5(and val1 = 5)?當我嘗試時,method_missing不會觸發,也不會發生錯誤消息。

回答

1

它一樣工作是,如果你做這樣的事情:

GlobalMemory.init { 
    self.val3 = 'value' 
} 

否則,它是從一個局部變量聲明沒有區別。我想更好的方式來做到這一點是有一個塊參數,寫你的init方法是這樣的:

GlobalMemory.init { |g| 
    g.val1 5 
    g.val2 "some string" 
    g.val3 = 'yeah' 
} 

我周圍有點混亂,試圖獲得VAR1 =解決方案使用#local_variables工作,但最近我可以來的是這樣的:

class Foo 
    def initialize(&bl) 
     @data = {} 
     b = yield self 
     still_to_assign = eval('local_variables', b) - eval('local_variables', bl) 
     still_to_assign.each { |v| r = eval(v,b); @data[v] = r } 
    end 
end 

Foo.new { 
    one = 1 
    two = 2 
    three = 3 
    binding 
} 

正如你所看到的,它需要你在塊的結尾處返回一個綁定對象。它也有一些變量已經在塊之前聲明過。也許有人可以建議一個更好的方法來做到這一點?

1

我不認爲這是可能做到這一點乾淨作爲一個內部的DSL