关闭不起作用

yuk*_*kas 17 ruby closures

如果一个块是一个闭包,为什么这个代码不起作用,以及如何使它工作?

def R(arg)
  Class.new do
    def foo
      puts arg
    end
  end
end

class A < R("Hello!")
end

A.new.foo #throws undefined local variable or method `arg' for #<A:0x2840538>
Run Code Online (Sandbox Code Playgroud)

sep*_*p2k 26

块是封闭的,arg确实可以在Class.new块内使用.它只是在foo方法内部不可用,因为它def启动了一个新范围.如果要更换defdefine_method,这需要一个块,你会看到你想要的结果:

def R(arg)
    Class.new do
        define_method(:foo) do
           puts arg
        end
    end
end

class A < R("Hello!")
end

A.new.foo # Prints: Hello!
Run Code Online (Sandbox Code Playgroud)

  • @Geo:使用带参数的块.例如`define_method(:add_one)do | x | x + 1结束 (2认同)

tad*_*man 5

如果动态定义类,可以根据需要更改它:

def R(arg)
  c = Class.new

  # Send the block through as a closure, not as an inline method
  # definition which interprets variables always as local to the block.
  c.send(:define_method, :foo) do
    arg
  end

  c
end

class A < R("Hello!")
end

puts A.new.foo.inspect
# => "Hello!"
Run Code Online (Sandbox Code Playgroud)