2012-01-06 33 views
0

有人能解释为什么最后的Yielder抛出一个没有给出的块?带有屈服的重新定义的方法抛出没有给出的块

class Foo 
    def yielder 
    yield "hello" 
    end 
end 

class Mod 

    def initialize 
    @@foo = Foo.new 
    end 

    def self.foo 
    @@foo 
    end 

end 

worker = Mod.new 

Mod.foo.yielder do |hello| 
    puts hello 
end 

Mod.foo.class.send(:define_method,:yielder) do 
    yield "new hello" 
end 

Mod.foo.yielder do |hello| 
    puts hello 
end 

给出:

你好
test.rb:27:在`块“:30:在没有`给出(产率)(LocalJumpError)
从test.rb块“

+0

这与'define_method'使用'instance_eval'有关,因为如果你使用'class_eval'和一个字符串,它的工作正常,而'instance_eval'给出相同的错误。尽管如此,仍然没有看到它:/ – 2012-01-06 21:46:45

回答

3

的简短介绍:

你不需要MOD-例如,如果你定义@@富了边initialize

你不需要国防部类来获取问题:

class Foo 
    def yielder 
    p 2 
    yield "hello" 
    end 
end 
foo = Foo.new 

foo.yielder do |hello| 
    puts hello 
end 

foo.class.send(:define_method,:yielder) do 
    p 1 
    yield "new hello" 
end 

foo.yielder do |hello| 
    puts hello 
end 

您可以再次缩短例如:

class Foo 
end 
foo = Foo.new 

foo.class.send(:define_method,:yielder) do 
    yield "new hello" 
end 

foo.yielder do |hello| 
    puts hello 
end 

这是一样的:

class Foo 
    define_method(:yielder) do 
    yield "new hello" 
    end 
end 

foo = Foo.new 
foo.yielder do |hello| 
    puts hello 
end 

介绍结束。

现在,我不知道我是否正确理解你想要的(如果我理解ruby是正确的;)) define_method接受一个块并将其用作方法体。 如果新的方法应该对自己收到的块,你必须在定义的接口定义,并称之为:

class Foo 
    define_method(:yielder) do | &prc | 
    prc.call("new hello") 
    end 
end 

foo = Foo.new 
foo.yielder do |hello| 
    puts hello 
end 

或者在你的例子同样的逻辑:

class Foo 
    def yielder 
    yield "hello" 
    end 
end 

class Mod 

    def initialize 
    @@foo = Foo.new 
    end 

    def self.foo 
    @@foo 
    end 

end 

worker = Mod.new 

Mod.foo.yielder do |hello| 
    puts hello 
end 

Mod.foo.class.send(:define_method,:yielder) do | &prc | 
    prc.call "new hello" 
end 

Mod.foo.yielder do |hello| 
    puts hello 
end 

要使代码更健壮,我会推荐一些与block_given?检查。

+0

它归结为发送'define_method'不允许相同的隐式块方法签名。 – 2012-01-06 22:08:44

+0

真实世界的使用需要它有时失败的方式。因此,这个问题,但非常感谢你一个精心制作的答案。 – patrick 2012-01-06 22:22:57

+0

哦,它也搞砸了rspec这个,我敢打赌这个案例对于rspec维护者来说很有趣,我会用你的好例子将它作为一个问题提交。我还在这里提供了关于ruby本身的链接和链接。 – patrick 2012-01-06 22:27:09

相关问题