ruby,define [] =运算符,为什么不能控制返回值?

jro*_*ind 10 ruby

试图做一些可能变成更有用的奇怪的东西,我试图[]=在自定义类上定义我自己的运算符,你可以做,并让它返回与value参数不同的东西,显然你不能这样做.[]=运营商的回报值始终是value; 即使重写此运算符,也无法控制返回值.

class Weird 
  def []=(key, value)
    puts "#{key}:#{value}"
    return 42
  end
end

x = Weird.new
x[:a] = "a"
  output "a:a"
  return value => "a"  # why not 42?
Run Code Online (Sandbox Code Playgroud)

有没有人对此有解释?有什么办法吗?

红宝石MRI 1.8.7.所有红宝石都是一样的; 它是语言的一部分吗?

Chr*_*sen 9

请注意,此行为也适用于所有赋值表达式(即属性赋值方法:) def a=(value); 42; end.

我的猜测是它以这种方式设计,可以很容易地准确理解用作其他表达式的一部分的赋值表达式.

例如,期望x = y.a = z[4] = 2:

  1. z.[]=(4,2)然后打电话
  2. y.a=(2)然后打电话
  3. 分配2给局部变量x,然后最终
  4. 产生2任何"周围"(或更低优先级)表达式的值.

这遵循最少惊喜原则 ; 相反,如果它最终等同于x = y.a=(z.[]=(4,2))(最终值受到两个方法调用的影响),那将是相当令人惊讶的.


虽然不完全权威,但Ruby编程必须说:

  • 编程Ruby(1.8),在表达式部分:

    赋值语句在其左侧(左值)设置变量或属性以引用右侧的值(右值).然后它返回该值作为赋值表达式的结果.

  • 编程Ruby 1.9(第3版)的第22.6节表达式,条件和循环:

    (在描述[]=方法调用之后)

    赋值表达式的值是它的右值.即使赋值是返回不同内容的属性方法,也是如此.

  • 请注意,使用`#send()`来调用赋值方法时,情况并非如此. (2认同)

Jos*_*Lee 5

它是一个赋值语句,它总是评估为赋值.让这种不同会很奇怪.

我想你可以x.[]= :a, "a"用来捕获返回值.

  • Nitpick:它不是赋值语句,它是赋值*表达式*.(如果是一个赋值语句,那么它就不会评估任何东西,因为它几乎是"语句"的*定义*.)实际上,Ruby根本就没有语句*,*所有*都是表达. (3认同)