构建器抛出“错误数量的参数”在 Ruby 1.9 中传递块时出错

发布于 2024-12-19 05:14:17 字数 986 浏览 1 评论 0原文

我正在尝试将 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

留蓝 2024-12-26 05:14:17

这实际上是因为在 ruby​​ 1.9 中,lambda 和 proc 的行为略有不同。想想 lambda,它在数学上是精确的,需要指定的参数的确切数量,而 proc 则表现出 ruby​​ 1.8 更宽松的行为。例如,

a = lambda {|v| p v }
a.call()     # ArgumentError: wrong number of arguments (0 for 1)
a.call(1)    # prints "1"
a.call(1, 2) # ArgumentError: wrong number of arguments (2 for 1)

b = proc {|v| p v }
b.call()     # prints "nil"
b.call(1)    # prints "1"
b.call(1, 2) # prints "1"

请注意,这两个对象都是 Proc 类型,但可以通过 .lambda? 来区分彼此。方法。

a.class   # => Proc
a.lambda? # => true
a.arity   # => 1  (number of parameters)
b.class   # => Proc
b.lambda? # => false
b.arity   # => 1  (number of parameters)

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,

a = lambda {|v| p v }
a.call()     # ArgumentError: wrong number of arguments (0 for 1)
a.call(1)    # prints "1"
a.call(1, 2) # ArgumentError: wrong number of arguments (2 for 1)

b = proc {|v| p v }
b.call()     # prints "nil"
b.call(1)    # prints "1"
b.call(1, 2) # prints "1"

Note that both objects are of type Proc, but can be distinguished from each other by the .lambda? method.

a.class   # => Proc
a.lambda? # => true
a.arity   # => 1  (number of parameters)
b.class   # => Proc
b.lambda? # => false
b.arity   # => 1  (number of parameters)
沙与沫 2024-12-26 05:14:17

哦哦,明白了。 Builder 中导致问题的行是这样的:

block.call(self)

换句话说,它将自身作为参数传递给块。在 Ruby 1.8 中,该块可以随意忽略这一点,但在 1.9 中,它必须声明所有参数。因此:

1.9.3p0 :023 > block = lambda { |dummy| puts "foo" }
1.9.3p0 :024 > @builder.content(&block)
foo

耶!

Ooh, figured it out. The line causing the problem in Builder is this:

block.call(self)

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:

1.9.3p0 :023 > block = lambda { |dummy| puts "foo" }
1.9.3p0 :024 > @builder.content(&block)
foo

Yay!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文