ruby - 在 Ruby 1.9 中传递 block 时生成器抛出 "wrong number of arguments"错误

标签 ruby lambda builder ruby-1.9 argument-error

我正在尝试将 Ruby 1.8 应用程序升级到 1.9,但在这里遇到了一些障碍。在 Ruby 1.8.7 中,我可以将一个 block 传递给 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)

传递一个实际的 block 而不是对一个 block 的引用是可行的:

1.9.3p0 :008 > @builder.content { puts "foo" }
foo

帮忙吗?

最佳答案

这实际上是因为在 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)

关于ruby - 在 Ruby 1.9 中传递 block 时生成器抛出 "wrong number of arguments"错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8320283/

相关文章:

java - 为什么可以使用类引用来创建 lambda 引用实例方法?

node.js - 如何在无服务器框架上包含静态文件?

cocoa - 下拉窗口编辑 Cocoa 弹出菜单项

ruby - 如何在没有 Ruby 的情况下获取 RUBY_PLATFORM 值?

ruby-on-rails - 将参数传递给 Rails Action 邮件程序

ruby - 在 ruby​​ 中创建带括号的符号

C#重构lambda表达式

java - 使用构建器模式进行 Spring 依赖注入(inject)

java - 在构造函数或类声明上注释 @Builder 有什么区别? ( Lombok )

ruby-on-rails - Rails 搜索/复选框逻辑