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

From: Shugo Maeda <shugo@...>
Date: 2019-12-26 06:52:00 UTC
List: ruby-list #50857
前田です。

On Thu, 26 Dec 2019 12:36:45 +0900
wanzerbusi@yahoo.co.jp wrote:
> [0 text/plain; charset=UTF-8]
> この問題簡単にクローズしないほうが良いかと思います。##もっと議論すべきでは。
> コードを一読したとき、私の感覚ですが、9になるべきと考えました。逆に48になるほうがおかしいと思いました。
> 根拠として私は
> a = a + (a = a + (a = a + (a = a + 5)))
> の式は
> a = 4a + 5
> と(厳密ではないかもしれませんが)等価と判断しております。であれば、9になって48になりえないです。

4aは4 * aという意味で書かれているかと思いますが、そう読み替えたとして
もRubyでは+はメソッド呼び出しなので、一般には両者が透過だとは言えません。
aがIntegerであれば通常はa + a + a + a + 5と4 * a + 5は同じ結果になりま
すが、例えばaがStringでしたら4 * aはTypeErrorになりますし、Integer#+が
再定義される可能性もあります。

また、関さんが最初に疑問に思われた^のケースでは上記のような式変形では
理解できませんので、[ruby-list:50854]でご説明したように、Rubyの式の評
価順序の結果として9になるとご理解いただいた方がよいと思います。

> また、初心者丸出しの誤解かもしれませんが、Rubyにおける変数は全てオブジェクトと解釈しております。ならば、なおさらa = 4a + 5
> の"="を解釈した際に初めて変数のオブジェクトが書き換えられるのではとも解釈しております。

Rubyの変数に格納されるのはオブジェクトへの参照のみですが、変数そのもの
はオブジェクトではなく、+と異なりa = 4a + 5の=はメソッド呼び出しでは
ありません。

> >自己代入の+=の場合は右辺を先に評価するような仕様の方が便利だったかもしれない
> と一足飛びに考えるのは私は早計と思料しております。##逆にこの一文が無ければ私は黙ってました><

「かもしれない」と書いただけでそのような仕様変更を提案しているわけでは
ありません。
ただ、x += yを評価順序も含めてx = x + yの構文糖としているのはRubyの言語
仕様としてそう決めているだけですので、x += yの場合は+の右辺を先に評価した
方が便利であれば、そういった言語仕様もありえたと思います。
XOR swapの例はRubyでは多重代入で事足りますので、他にもその方が便利なケ
ースがもしあれば、という意味で「かもしれない」と書きました。
# なかださんが書かれているようにCでもポータブルな書き方ではないようですが。

In This Thread