元编程访问局部变量

时间:2010-10-24 11:30:24

标签: ruby metaprogramming

class Foo
  def initialize
    bar = 10
  end
  fiz = 5
end

是否有可能获得这些本地值(课外)?

3 个答案:

答案 0 :(得分:3)

初始化中的局部变量将丢失。

您可以在类之外获取值fiz,但只能在定义该类时,并记录该类定义的返回值。

return_of_class_definition = (class A ; fiz = 5 ; end)会将fiz的值赋给变量。

您也可以使用binding,但当然,这意味着更改课程,这可能不允许进行练习。

class A
  bin = 15
  $binding = binding
end

p eval 'bin', $binding

答案 1 :(得分:2)

没有。一旦局部变量超出范围(对于initialize方法运行时的条形 - 对于fiz,当达到类定义的end时,它就消失了。没有留下痕迹。

虽然局部变量仍然在范围内,但您可以使用local_variables查看它(及其名称),并使用eval获取并设置其值(尽管出于理智原因,绝对不建议这样做),但是一旦超出范围,那就是它。无法取回它。

答案 2 :(得分:1)

在ruby中,我们可以调用范围门 - 当用ruby编写的程序离开前一个范围时。这些门是:classmodule和方法(def关键字)。换句话说,在代码中的classmodule def关键字后,您将立即进入新范围。

在ruby嵌套的可见性中不会发生,一旦你创建了一个新的作用域,先前的绑定将被一组新的绑定替换。

例如,如果您定义以下类:

x = 1
class MyClass
  # you can't access to x from here
  def foo
    # ...from here too
    y = 1
    local_variables
  end
end

local_variables方法调用将返回[:y]。这意味着我们无法访问x变量。您可以使用名为 Flat Scopes 的ruby技术解决此问题。基本上,使用class关键字定义类,您可以使用Class.new定义它,并将块传递给此调用。显然,一个块可以从定义它的范围中获取任何局部变量,因为它是一个闭包!

我们之前的例子可以改写成类似的东西:

x = 1
Foo = Class.new do
  define_method :foo do
    i_can_do_something_with(x)
    y = 1
    local_variables
  end
end

在这种情况下,local_variables将返回[:x, :y]