Reference Method Parameter in Class::new block
我正在尝试根据以下问题在 Ruby 中使用元编程创建类:Dynamicly define named classes in Ruby。一切进展顺利,除了似乎在 Class.new 的块中无法引用奇怪的方法参数。
我有这个
1
2 3 4 5 6 7 8 9 10 11 12 |
class A; end
module B |
但是当我有上面的然后用
测试它
1
2 |
B.class_with_method ‘ExampleClass’, 23
B::ExampleClass.new.example |
给我
undefined local variable or method `method_return’ for # (NameError)
这很奇怪,因为如果我要这样做
1
2 3 4 5 6 |
def add_number(number)
[1, 2, 3, 4].map {|i| i + number} end add_number(2) |
很明显,块可以接受方法参数。
有没有办法在块内将 method_return 传递给 def example?
这一点也不奇怪,这是方法定义的常规行为:
1
2 3 4 5 6 7 8 |
class A
x = 3 def foo x end end A.new.foo # NameError: undefined local variable or method `x’ |
方法定义不会从其外部范围捕获局部变量。这通常是好的:通常您不希望方法的结果依赖于其定义时存在的某些随机状态,您希望它依赖于您调用它的对象!
当然,当您进行元编程时除外。在这种情况下,捕获局部变量很有用,因此您可以使用与其他地方相同的机制显式捕获它们:块。
1
2 3 |
define_method :example do
method_return end |
因为 method_return 是一个变量,所以你不能将它向下传播到 example 方法,除非你在另一个上下文中使用它。您可以在类级变量中捕获它:
1
2 3 4 5 6 7 |
klass = Class.new(A) do
@@method_return = method_return def example |
您还可以动态定义方法,以便块将 method_return 变量捕获为闭包:
1
2 3 4 5 |
klass = Class.new(A) do
define_method(:example) do method_return end end |
当使用 def example 时,块范围会发生变化并变得完全不同。
- 啊,那不是类实例变量,那是类变量!完全不一样的东西!
- @max 我的意思是”类变量的实例”,但也许可以更好地表述。已编辑。
def 结构关闭了它的作用域。局部变量不能超越这一点。要执行您想要的操作,请改用 define_method。
来源:https://www.codenong.com/48774252/