我想寫一個方法(define_variables
),它可以得到block
並使用它定義的變量。可能嗎?例如,我想得到5輸出:是否可以在方法中訪問塊的作用域?
module A
def self.define_variables
yield
puts a # not 5 :(
end
end
A::define_variables do
a = 5
end
也許有一些技巧與eval,但還沒有找到任何人。
我想寫一個方法(define_variables
),它可以得到block
並使用它定義的變量。可能嗎?例如,我想得到5輸出:是否可以在方法中訪問塊的作用域?
module A
def self.define_variables
yield
puts a # not 5 :(
end
end
A::define_variables do
a = 5
end
也許有一些技巧與eval,但還沒有找到任何人。
總之,沒有。在你調用yield
之後,那些在塊中定義的變量是不見了(我們將會看到),除了返回的內容 - 這就是範圍的工作原理。在你的例子中,5
仍然在那裏,它是由塊返回,因此puts yield
將打印5
。使用這個,你可以從塊{:a => 5}
返回一個散列,然後以這種方式訪問多個「變量」。在Ruby 1.8(在IRb only),你可以這樣做:
eval "a = 5"
a # => 5
雖然我不知道塊的反正eval
內容。無論如何,in Ruby 1.9 the scope of eval
was isolated,這會給你一個NameError
。您可以在Binding
的範圍內做一個eval
雖然:
def foo
b = yield
eval(a, b) + 2
end
foo do
a = 5
binding
end # => 7
在我看來,你試圖做的是模仿宏在Ruby中,這僅僅是不可能的(at least not pure Ruby),和我勸阻使用上面提到的任何「解決方法」。
一致認爲這是一個倒退,安德魯的解釋是正確的。如果你的使用情況是定義的變量,但是,已經有class_variable_set
和instance_variable_set
方法,爲了這個,是偉大的:
module A
def self.define_variables(vars = {})
vars.each { |n, v| class_variable_set n, v }
puts @@a
end
end
A::define_variables :@@a => 5
以上是你越已經發布,而如何將代碼內工作的例子比推薦。
用實例/類變量繞過整個範圍問題肯定會讓'')''更容易推理。 – 2012-02-12 03:10:09
我試圖看看我可以用給定的代碼來完成工作。看着這很聰明。 – ericraio 2012-02-12 03:19:31
這是什麼實際使用情況?這對我來說似乎倒退了。 – 2012-02-12 02:42:34
如果您想利用在已傳遞的塊內進行的一些計算,最好的辦法是從該塊返回一些內容並對其進行處理。依賴傳遞的proc中的局部變量的命名沒有多大意義。什麼是保證某人使用「a」作爲變量?當你不想要的時候,你會如何防止任意proc跺跺自己的變量? – 2012-02-12 04:24:39
我想爲簡單的控制檯遊戲製作一個'GameWorld'模塊,這個模塊有'load'和'run'方法。 load方法加載game_objects並將它們存儲在數組中,'run'來描述它們之間的一些交互。在GameWorld的範圍中,我可以訪問game_objects數組並輸出一些信息(健康狀況,分數等)。只是爲了「對稱」和學習的目的,我試圖用這兩種方法使用塊。現在,我將對象直接加載到模塊的常量「game_objects」中。無論如何,非常感謝您的幫助,現在我們越來越清楚範圍和區塊的工作方式。 – evfwcqcg 2012-02-12 04:54:08