闭包不起作用。

17

如果一个块是一个闭包,为什么这段代码不起作用,该如何使其起作用?

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>

你能让我们看到你的错误信息吗? - samoz
错误信息在示例的注释中。 - Yury Kaspiarovich
2个回答

26

块是闭包,arg确实在Class.new块内可用。只是因为def开始一个新的作用域,所以它在foo方法内不可用。如果您将def替换为采用块的define_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!

一个带参数的方法应该如何定义? - Geo
2
@Geo:使用带参数的块。例如 define_method(:add_one) do |x| x+1 end - sepp2k

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!"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接