[ruby-list:50854] Re: [質問]自己代入を繋げた場合の動作について

From: Shugo Maeda <shugo@...>
Date: 2019-12-25 01:51:56 UTC
List: ruby-list #50854
前田です。

On Wed, 25 Dec 2019 00:06:37 +0900
"関優輔" <t181d035@gmail.com> wrote:
> aをIntegerの変数として、1を代入した状態で
> a += a += a += a += 5
> を実行してからaを出力すると期待する出力は48ですが実際には9が出力されます。
> 48の根拠は(5+1)*2*2*2=48ということと、Cを含む他の言語で48になるということです。
> 自己代入を繋げて書かずに分けて書くと期待する値になります。
> 
> これはRubyの仕様 なのでしょうか。それともバグなのでしょうか。

Rubyではx += yはx = x + yの構文糖なので

  a += a += a += a += 5

は

  a = a + (a = a + (a = a + (a = a + 5)))

と同じ意味になります。

また、x + yの評価順序は

  1. xの評価
  2. yの評価
  3. 「xの評価結果.+(2の評価結果)」というメソッド呼び出し

ですので、+の左辺のaはすべて右辺よりも先に評価されて、初期値の1になります。
ということで、5に1が4回加算されて9になるのは現状では仕様だと思います。
JavaScriptでも結果は9になるようです。
# Pythonはどうかなと思ったらPythonは+=が文なの文法エラーでした。

過去に議論があったか思い出せませんが、自己代入の+=の場合は右辺を先に評
価するような仕様の方が便利だったかもしれないですね。

In This Thread