请考虑以下代码段:
class Example
  def my_attr=(value)
    @_my_attr = value
    @_my_attr * 3
  end
end
我希望表达式Example.new.my_attr = 5返回15,但结果证明是错误的.即使我=明确调用该方法,也始终返回原始返回值:
Example.new.my_attr = 5 # => 5
Example.new.my_attr=(5) # => 5
Ruby如何以及为什么这样做?Ruby是否会处理=特别结束的方法,还是其他机制?我想这排除了链接=方法的返回值,对吧?有没有办法让Ruby的行为有所不同,或者这是怎么回事?
更新:感谢@jeffgran:
Example.new.send(:my_attr=, 5) # => 15
这是一种解决方法,但在另一个层面上甚至更令人困惑,因为这意味着send在行为方面显然并不总是直接调用方法.
mea*_*gar 21
这就是作业的工作原理; 返回值被忽略,赋值表达式的结果始终是右侧值.这是Ruby语法的基本特征.无论左手边是变量(),方法,常量()还是任何表达式,left-hand side = right-hand side总是会评估为.right-hand sidex(object.x)X
来源:编程语言| Ruby IPA Ruby Standardization WG Draft,11.4.2.2.5,Single method assignment
考虑分配链接,x = y = 3.
为了使其正常工作,结果y = 3 必须是3,无论y=方法返回的实际值如何.x = y = 3旨在为已读y = 3; x = 3,不是因为y = 3; x = y它是如果返回值从什么会暗示y=被作为的结果处理y = 3.
或者考虑可以使用所有其他地方的分配.有时候,而不是......
obj.x = getExpensiveThing()
if obj.x 
  ...
......我们写这个......
if obj.x = getExpensiveThing()
这不能工作,如果结果obj.x = ...可以是任意的事情,但我们知道它会奏效,因为结果obj.x = y是永远 y.
更新
对该问题的评论指出:
有趣的是,我没有意识到这种情况.似乎method =返回给出的任何输入...
不,这是一个重要的区别.这与方法赋值的返回值无关,它肯定不会 "返回给出的任何输入",它返回你告诉它返回的任何内容.
重点是语言的语法忽略了返回值; 赋值不会计算attr=方法的返回值,但返回值仍然存在,如问题本身所示:Example.new.send(:my_attr=, 5) # => 15.这是有效的,因为它不是任务.你是支持Ruby语言的那一部分.
再次更新
要明确:x并且y在我的示例中不应该被解释为文字Ruby变量,它们是任务的任何有效左侧的占位符.x或者y可以是任意表达式:a,obj.a,CONSTANT_A,Something::a,@instance_a,这都是一样的.任务的价值始终是右手边.
| 归档时间: | 
 | 
| 查看次数: | 276 次 | 
| 最近记录: |