ruby - 如何将 block 传递给名称以等号结尾的方法?

标签 ruby

这听起来很奇怪不是吗?

class Dummy
  def foo=(value); end
end

Dummy.new.foo = 1 { |x| x } # => syntax error
Dummy.new.foo=(1) { |x| x } # => syntax error

我尝试了空格、括号、逗号的每一种排列;没有运气。我很困惑。我从不怀疑以“=”结尾的方法是特殊的。这是一个错误吗?是故意的吗?如果有意,为什么?有记录吗?在哪里?请分享见解。

谢谢

附言。 ruby 是 1.9.2p290(2011-07-09 修订版 32553)[x86_64-darwin11.0.1]

最佳答案

= 结尾的方法的语法糖确实让它变得特别。您仍然可以做一些事情,比如向该方法传递多个参数,或者传递一个 block ,但不是以任何漂亮或方便的方式:

class Foo
  def bar=(a,b=nil)
    p [a,b]
    if block_given?
      yield "hi"
    else
      puts "No block"
    end
  end
end

f = Foo.new
f.bar = 42
#=> [42, nil]
#=> No block

f.bar = 42, 17
#=> [[42,17], nil]
#=> No block

f.send(:bar=,42,17) do |x|
  puts "x is #{x.inspect}"
end
#=> [42, 17]
#=> x is "hi"

这些方法的另一个特殊之处在于,当使用语法糖调用时,它们的计算结果是正确的值,而不是方法的返回值:

class Foo
  def bar=(a)
    return 17 # really explicit
  end
end

f = Foo.new

x = (f.bar = 42)
p x
#=> 42

x = f.send(:bar=,42)
p x
#=> 17

关于ruby - 如何将 block 传递给名称以等号结尾的方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9009814/

相关文章:

ruby-on-rails - object_id 方法与 Fixnum 对象和 String 对象的区别

ruby-on-rails - 模拟时遇到问题 `Resolv::DNS.open`

Ruby:捕获输出

ruby-on-rails - 如何使此正则表达式规则不区分大小写

ruby-on-rails - Ruby on Rails 将表与数量连接起来

ruby-on-rails - 在 Rails 中使用插入查询遍历大数据的最佳方法是什么

ruby - Ruby 版本管理器 (rvm) 的替代品有哪些?

ruby - 将字符串转换为现有的类实例

ruby - Datamapper - 奇怪的可能不是 NULL 错误

ruby-on-rails - PG::UndefinedTable:错误:关系“productsrules”不存在