为什么 `method=` 不像任何其他方法那样对待? [英] Why isn't `method=` treated the same as any other method?

查看:48
本文介绍了为什么 `method=` 不像任何其他方法那样对待?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑以下代码片段:

class Example
  def my_attr=(value)
    @_my_attr = value
    @_my_attr * 3
  end
end

我希望表达式 Example.new.my_attr = 5 返回 15,但结果是错误的.始终返回原始返回值,即使我显式调用 = 方法:

I expect the expression Example.new.my_attr = 5 to return 15, but that turns out to be wrong. The original return value is always returned, even when I call the = method explicitly:

Example.new.my_attr = 5 # => 5
Example.new.my_attr=(5) # => 5

Ruby 如何以及为什么这样做?Ruby 是否特别对待以 = 结尾的方法,还是其他某种机制?我想这排除了 = 方法的返回值的链接,对吗?有没有办法让 Ruby 表现得不同,或者就是这样?

How and why does Ruby do this? Does Ruby treat methods that end in = specially, or is it some other mechanism? I guess this precludes chaining on return values of = methods, right? Is there a way to make Ruby behave differently, or is this just how it is?

更新:感谢@jeffgran:

Update: Credit to @jeffgran for this:

Example.new.send(:my_attr=, 5) # => 15

这是一种解决方法,但在另一个层面上更令人困惑,因为这意味着 send 在行为上显然并不总是等同于直接调用方法.

This is a workaround, but on another level even more perplexing, since that would mean send is clearly not always equivalent in behavior to calling a method directly.

推荐答案

这就是赋值的工作方式;返回值被忽略,赋值表达式的结果总是右边的值.这是 Ruby 语法的一个基本特征.left-hand side = right-hand side 将始终计算为 right-hand side,无论左侧是否为变量 (x)、方法 (object.x)、常量 (X) 或任何表达式.

This is how assignment works; the return value is ignored, and the result of an assignment expression is always the right-hand value. This is a fundamental feature of Ruby's grammar. left-hand side = right-hand side will always evaluate to right-hand side, regardless of whether left hand side is a variable (x), a method (object.x), a constant (X) or any expression.

来源:编程语言 |红宝石IPA Ruby 标准化工作组草案,11.4.2.2.5,单一方法分配

Source: Programming Languages | Ruby IPA Ruby Standardization WG Draft, 11.4.2.2.5, Single method assignments

考虑分配链式,x = y = 3.

为了使其正常工作,y = 3 必须的结果是3,而不管返回的实际值>y= 方法.x = y = 3 表示为 y = 3;x = 3, 不是 y = 3;x = y 如果 y= 的返回值被视为 y = 3 的结果,这将是隐含的.

For this to work correctly, the result of y = 3 must be 3, regardless of the actual value returned by the y= method. x = y = 3 is meant to read as y = 3; x = 3, not as y = 3; x = y which is what would be implied if the return value from y= was treated as the result of y = 3.

或者考虑可以使用所有其他位置分配.有时,而不是这个...

Or consider all the other places assignment can be used. Sometimes, instead of this...

obj.x = getExpensiveThing()
if obj.x 
  ...

...我们写这个...

... we write this ...

if obj.x = getExpensiveThing()

如果 obj.x = ... 的结果可能是任意的,这 不能工作,但我们知道会起作用,因为 obj.x = y 的结果是 always y.

This couldn't work if the result of obj.x = ... could be any arbitrary thing, but we know it will work because the result of obj.x = y is always y.

更新

A 评论 问题说明:

有趣的是,我不知道这种情况.似乎 method= 返回给定的任何输入...

Interesting, I wasn't aware of this scenario. It seems that method= returns whatever input is given...

,这是一个重要的区别.这与方法赋值的返回值无关,而且它绝对不会返回给定的任何输入",它返回您告诉它返回的任何内容.

No, it's an important distinction to make. This has nothing to do with the return value of method assignment, and it definitely does not "return whatever input is given", it returns whatever you tell it to return.

重点是返回值被语言的语法忽略了;赋值不计算attr=方法的返回值,但问题本身证明返回值仍然存在:Example.new.send(:my_attr=, 5) # =>15.这是有效的,因为它不是分配.您正在回避 Ruby 语言的这一部分.

The whole point is that the return value is ignored by the grammar of the language; assignment doesn't evaluate to the return value of the attr= method, but the return value still exists as evidenced by the question itself: Example.new.send(:my_attr=, 5) # => 15. This works because it is not assignment. You're side-stepping that part of the Ruby language.

再次更新

需要明确的是:我的示例中的 xy 不应被解释为文字 Ruby 变量,它们是任何有效左手的占位符任务的一面.xy 可以是任何表达式:aobj.aCONSTANT_ASomething::a@instance_a都一样.assignment 的值总是在右边.

To be clear: x and y in my examples shouldn't be interpreted as literal Ruby variables, they are place holders for any valid left-hand side of an assignment. x or y could be any expression: a, obj.a, CONSTANT_A, Something::a, @instance_a, it's all the same. The value of assignment is always the right-hand side.

这篇关于为什么 `method=` 不像任何其他方法那样对待?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆