buto > /dev/null

だいたい急に挑戦してゴールにたどり着かずに飽きる日々です

Ruby インクリメント演算子が使えない理由

昨日、夜中の空腹をまぎらわせるためにRubyをインストールしてみました 今朝から制御構文などの基礎コードを書いていたのですが、num++のような インクリメント演算子が使えないことが分かり「なんで?」と気になったので調べました

理由:Rubyでは数値もオブジェクトだから

こちらのブログで分かりました! Ruby にインクリメント演算子のようなものが無い理由

インクリメント演算子が利用できない理由をRuby開発者が以下のように語っています

[ruby-list:5323] Re: Questions on specs and threads

3) 記号的な記法
これは単なる私の趣味ですが, 単項インクリメントとかがたまに欲しく
なります. i += 1 でいいわけですが. i++ と書いて怒られる (^^;

すんません.この件は以前から指摘されているのですが(演算子はC に似ているのに++と--は対応する演算子が無い),++の動作が本質 的に「変数を操作する」ものであるため,変数がオブジェクトでな いRubyでは導入できないでいます.++や--の「オブジェクト指向的 意味」がRubyの他の部分と整合性を保ったまま定義できれば採用し たいのですが….

Rubyは変数の操作をさせたくない言語なんですね 「変数がオブジェクトでない」ってどういうことなんだろう??

Rubyでは変数がオブジェクトでない」とは

【Ruby公式サイト】JavaからRubyへより

Javaと違って、Rubyは… 2や3.14159といった数値も含めて、すべてのものはオブジェクトです。

変数numは(numそのものが)オブジェクトではなくて、数値オブジェクトへの参照 → 1つの数値オブジェクトを共有している

# 変数numには123そのものではなく
# 123へのアドレスが格納されている

num = 123
puts num.object_id # 247が出力される

num_cp = 123
puts num_cp.object_id # 247が出力される

変数はオブジェクトへの参照だから、「変数自体がオブジェクトでない」ってことなんですね

数値オブジェクトはimmutable

上記コードのようにnumnum_cpは1つの数値オブジェクトを参照している → 数値オブジェクト「123(object_id:247)」自体が操作されたら、   参照している変数の値が全部変わっちゃう!!

なので、数値オブジェクトはimmutable(不変、final)になっている 以下のコードは変数の値を操作しているように見えるが、参照先を付け替えているだけ

cnt = 123
puts cnt.object_id # 247が出力される

cnt = 456
puts cnt.object_id # 913が出力される

参照している数値オブジェクトを付け替えることによって数値オブジェクト自体は操作されずに 変数の値が操作されているように見える!

インクリメント演算子は数値オブジェクトの操作を意味する

もう一度、最初に引用した開発者のコメントを見てみます

++の動作が本質的に「変数を操作する」ものであるため,変数がオブジェクトでな いRubyでは導入できないでいます.

インクリメント演算子は数値オブジェクト自体に加算することを意味するので、 Rubyの「数値オブジェクトはimmutable」のルールと合わなくてサポートされていない

言語って奥が深い!!

Rubyでインクリメント演算子がサポートされていないことにもちゃんと理由があった! Pythonも同じ理由でインクリメント演算子をサポートしていないらしい(使えると勘違いしていた)

このテーマとは違いますが、調べている時に「各言語のメモリの使い方」の解説に遭遇して とても面白かったです メモリとスタックとヒープとプログラミング言語