构建器抛出“错误数量的参数”在 Ruby 1.9 中传递块时出错
我正在尝试将 Ruby 1.8 应用程序升级到 1.9,但在这里遇到了一些障碍。在 Ruby 1.8.7 中,我可以将一个块传递给 Builder 3.0.0,它会按预期被调用:
1.8.7 :003 > @builder = Builder::XmlMarkup.new
1.8.7 :004 > block = lambda { puts "foo" }
1.8.7 :005 > @builder.tag(&block)
foo
但在 1.9 中,我收到此错误:
1.9.3p0 :002 > @builder = Builder::XmlMarkup.new
1.9.3p0 :003 > block = lambda { puts "foo" }
1.9.3p0 :004 > @builder.content(&block)
ArgumentError: wrong number of arguments (1 for 0)
from (irb):3:in `block in irb_binding'
from /Users/dev/.bundle/ruby/1.9.1/gems/builder-3.0.0/lib/builder/xmlbase.rb:155:in `call'
...
并将其重写为稳定 lambda(这只是语法糖,对吧?)没有帮助:
1.9.3p0 :006 > block = -> { puts "foo" }
1.9.3p0 :007 > @builder.content(&block)
ArgumentError: wrong number of arguments (1 for 0)
传递一个实际的块而不是对块的引用确实有效:
1.9.3p0 :008 > @builder.content { puts "foo" }
foo
帮助?
I'm trying to upgrade a Ruby 1.8 app to 1.9 and hit a bit of a roadblock here. In Ruby 1.8.7, I can pass on a block to Builder 3.0.0 and it gets called as expected:
1.8.7 :003 > @builder = Builder::XmlMarkup.new
1.8.7 :004 > block = lambda { puts "foo" }
1.8.7 :005 > @builder.tag(&block)
foo
But in 1.9, I get this error:
1.9.3p0 :002 > @builder = Builder::XmlMarkup.new
1.9.3p0 :003 > block = lambda { puts "foo" }
1.9.3p0 :004 > @builder.content(&block)
ArgumentError: wrong number of arguments (1 for 0)
from (irb):3:in `block in irb_binding'
from /Users/dev/.bundle/ruby/1.9.1/gems/builder-3.0.0/lib/builder/xmlbase.rb:155:in `call'
...
And rewriting that as a stabby lambda (which is just syntactic sugar, right?) doesn't help:
1.9.3p0 :006 > block = -> { puts "foo" }
1.9.3p0 :007 > @builder.content(&block)
ArgumentError: wrong number of arguments (1 for 0)
Passing an actual block instead of a reference to one does work:
1.9.3p0 :008 > @builder.content { puts "foo" }
foo
Help?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这实际上是因为在 ruby 1.9 中,lambda 和 proc 的行为略有不同。想想 lambda,它在数学上是精确的,需要指定的参数的确切数量,而 proc 则表现出 ruby 1.8 更宽松的行为。例如,
请注意,这两个对象都是 Proc 类型,但可以通过 .lambda? 来区分彼此。方法。
That is actually because in ruby 1.9, lambda and proc behave subtly differently. Think of lambda, being mathematically precise, requiring the exact number of arguments specified, while proc exhibits the more permissive behavior of ruby 1.8. For example,
Note that both objects are of type Proc, but can be distinguished from each other by the .lambda? method.
哦哦,明白了。 Builder 中导致问题的行是这样的:
换句话说,它将自身作为参数传递给块。在 Ruby 1.8 中,该块可以随意忽略这一点,但在 1.9 中,它必须声明所有参数。因此:
耶!
Ooh, figured it out. The line causing the problem in Builder is this:
In other words, it passes itself as an argument to the block. In Ruby 1.8, the block is free to ignore this, but in 1.9, it must declare all arguments. Thus:
Yay!