我一直試圖建立一個系統,我可以生成一系列類似的Ruby類,通過整型參數進行區分,我將其保存到相關類的類變量中 - 類似於C++模板。動態定義的類錯誤地共享數據 - 錯誤或編碼錯誤?
但是,引用(因此,創建)模板類的新版本會覆蓋以前版本中保存的參數,並且我無法解決原因。
這裏有一個小例子
class Object
def self.const_missing(name)
if name =~ /^Templ(\d+)$/
return make_templ $1.to_i
else
raise NameError.new("uninitialised constant #{name}")
end
end
private
def make_templ(base)
# Make sure we don't define twice
if Object.const_defined? "Templ#{base}"
return Object.const_get "Templ#{base}"
else
# Define a stub class
Object.class_eval "class Templ#{base}; end"
# Open the class and define the actual things we need.
Object.const_get("Templ#{base}").class_exec(base) do |in_base|
@@base = in_base
def initialize
puts "Inited with base == #{@@base}"
end
end
Object.const_get("Templ#{base}")
end
end
end
irb(main):002:0> Templ1.new
Inited with base == 1
=> #<Templ1:0x26c11c8>
irb(main):003:0> Templ2.new
Inited with base == 2
=> #<Templ2:0x20a8370>
irb(main):004:0> Templ1.new
Inited with base == 2
=> #<Templ1:0x261d908>
我找到我的Ruby中的錯誤(紅寶石1.9.2p290(2011-07-09)[I386-的mingw32]),或有我只是編碼出錯了?
嗯,我花了45分鐘試圖算出這個,我猜,因爲你正在運行的'Object'類中的塊的東西是錯的變量綁定。然而,我不能拿信用的答案,因爲我終於找到了解釋懷疑在這裏:http://stackoverflow.com/questions/10109925/ruby-unexpected-results-from-class-exec-when-defining-class-變量。您的解決方案是將該塊轉換爲字符串並對其進行評估,以便將其編譯到正確的上下文中。 – Casper
@Casper當答案是「使用字符串評估而不是塊評估」時,通常是搜索更好的答案的時候。字符串評估是危險和脆弱的,有時候是你需要的,但是我估計有超過95%的時間我看到它被使用,這是一種不太危險的表單。 – dbenhur