2012-08-26 108 views
2

我有以下代碼:如何在Ruby中爲eval創建單獨的命名空間?

code = "def hi; \"hi!\"; end" 
eval code 

hi == "hi!" # true 

我可以訪問方法hi,因爲當它在所評估的代碼被定義,它被定義爲主要物體的方法。

然而,這也意味着,評估的代碼可以訪問的東西我定義之外呢:

def hi; "hi!"; end 
eval "hi == \"hi\"" # => true 

我想有一個單獨的命名空間中,我可以運行評估代碼;我會怎麼做?

我嘗試玩module_eval並使用模塊作爲命名空間,但我無法獲得它來定義方法或類,並在另一個評估中訪問它。

回答

2

你可以像這樣的對象的內部評估代碼:

module DSL 
    def helper_method_to_be_used_by_evaled_code 
     # ... 
    end 

    # ... 
    end 

    container = Object.new 
    container.extend(DSL) 
    File.open(eval_file1, 'r') {|f| container.instance_eval(f.read, eval_file1)} 
    File.open(eval_file2, 'r') {|f| container.instance_eval(f.read, eval_file2)} 

有了這個,你可以控制是否保留evals與否之間定義:您可以重複使用container實例或處置,並創建新的。這將適用於方法定義和常量,在這些調用之間不保留局部變量。

此外,而不是Object你可能想看看BlankState模式。 「blankslate」就是一個例子。

0

它似乎並不像你所談論的製作評估代碼的模塊組成部分,所以這樣的事情應該只是罰款:

module EvalMethods 
    class << self 
    code = "def hi; \"hi!\"; end" 
    eval code 
    end 
end 

puts EvalMethods::hi == "hi!" 
+0

我需要能夠執行第二個評估,我可以訪問任何以前的定義..我怎麼能做到這一點? –

相關問題