开发者

Closure doesn't work

开发者 https://www.devze.com 2022-12-21 01:06 出处:网络
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

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

精彩评论

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