Ruby 是否可以访问块';方法中的范围是什么?

Ruby 是否可以访问块';方法中的范围是什么?,ruby,Ruby,我想写一个方法(define_variables),它可以得到一个块,并使用其中定义的变量。可能吗?例如,我希望在输出中得到5: module A def self.define_variables yield puts a # not 5 :( end end A::define_variables do a = 5 end 也许eval有一些技巧,但还没有找到任何人。简言之,没有。在调用yield之后,块中定义的那些变量就消失了(有点像我们将看到的那样),除了

我想写一个方法(
define_variables
),它可以得到一个
,并使用其中定义的变量。可能吗?例如,我希望在输出中得到5:

module A
  def self.define_variables
    yield
    puts a # not 5 :(
  end
end

A::define_variables do
  a = 5
end

也许eval有一些技巧,但还没有找到任何人。

简言之,没有。在调用
yield
之后,块中定义的那些变量就消失了(有点像我们将看到的那样),除了返回的内容,这就是scope的工作方式。在您的示例中,
5
仍然存在,因为它是由块返回的,因此
put-yield
将打印
5
。使用这种方法,您可以从块
{:a=>5}
返回一个散列,然后以这种方式访问多个“变量”。在Ruby 1.8(In)中,您可以执行以下操作:

eval "a = 5"
a # => 5
尽管我不知道如何去理解一个区块的内容。无论如何,这将给您一个
名称错误
。您可以在以下情况下执行
eval


在我看来,你要做的是在Ruby中模拟宏,这是不可能的(),我不鼓励使用我上面提到的任何“变通方法”。

同意这有点倒退,Andrew的解释是正确的。但是,如果您的用例正在定义变量,那么已经有
class\u variable\u set
instance\u variable\u 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

以上更多的是一个示例,说明它在您发布的代码中如何工作,而不是一个建议。

这方面的实际用例是什么?在我看来,这似乎很落后。如果你想利用在通过的块中进行的一些计算,你最好的办法是从该块中返回一些东西并对其进行处理。在传递的过程中依赖局部变量的命名没有多大意义。如何保证有人使用“a”作为变量?你如何防止任意进程在你不想的时候践踏你自己的变量?我试图为简单的控制台游戏制作一个
GameWorld
模块,这个模块有
load
run
方法。加载方法加载游戏对象并将其存储在数组中,
运行
来描述它们之间的一些交互。在GameWorld的范围内,我可以访问game_对象数组并输出一些信息(健康、分数等)。为了“对称”和学习的目的,我试着在两种方法中使用块。现在,我将对象直接加载到模块的常量中,该常量名为
game\u objects
。无论如何,非常感谢您的帮助,现在范围和块的工作原理越来越清楚了。使用实例/类变量绕过整个范围的问题,当然可以更容易地解释
:)
。我试着看看如何使用给定的代码使其工作。看着这个真是太聪明了。
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