元编程访问局部变量
class Foo def initialize bar = 10 end fiz = 5 end
是否有可能获得这些本地值(课外)?
初始化中的局部变量将丢失。
您可以在类之外获取值fiz,但只能在定义该类时,并记录该类定义的返回值。
return_of_class_definition = (class A ; fiz = 5 ; end)
将fiz的值赋给变量。
您也可以使用binding
但当然,这意味着更改类,这可能不允许进行练习。
class A bin = 15 $binding = binding end p eval 'bin', $binding
不会。一旦局部变量超出范围(对于initialize
方法运行时的fiz
当达到类定义end
时为fiz
),它就消失了。 没有痕迹了。
虽然局部变量仍在范围内,但您可以使用local_variables
查看它(其名称),并使用eval
获取并设置其值(尽管出于理智原因,这绝对不建议使用),但是一旦它超出范围,那就是它。 无法取回它。
在ruby中,我们可以调用范围门 – 当用ruby编写的程序离开前一个范围时。 这些门是: class
, module
和方法( def
关键字)。 换句话说,在class
,代码中的def
关键字module
会立即进入新的范围。
在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
您可以使用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]
。