是否可以在方法中访问块的范围?
我想编写方法( 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 )中,您可以:
eval "a = 5" a # => 5
虽然我不知道要eval
一个块的内容。 无论如何, 在Ruby 1.9中, eval
的范围是孤立的 ,这会给你一个NameError
。 您可以在Binding
的上下文中执行eval
:
def foo b = yield eval(a, b) + 2 end foo do a = 5 binding end # => 7
在我看来,你想要做的是在Ruby中模拟宏,这是不可能的( 至少不是纯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
以上是一个如何在您发布的代码中工作而不是推荐的示例。