开发者

Closure doesn't work

If a block is a closure, why does this code does not work, and how to make it work?

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

class A < R("Hello!")
end

A.new.foo #throws unde开发者_运维知识库fined local variable or method `arg' for #<A:0x2840538>


Blocks are closures and arg is indeed available inside the Class.new block. It's just not available inside the foo method because def starts a new scope. If you replace def with define_method, which takes a block, you'll see the result you want:

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!


If you define the class dynamically, you can alter it as you like:

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜