BETA

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

投稿日:2020-08-10
最終更新:2020-08-10

昨日、夜中の空腹をまぎらわせるために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も同じ理由でインクリメント演算子をサポートしていないらしい(使えると勘違いしていた)

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

技術ブログをはじめよう Qrunch(クランチ)は、プログラマの技術アプトプットに特化したブログサービスです
駆け出しエンジニアからエキスパートまで全ての方々のアウトプットを歓迎しております!
or 外部アカウントで 登録 / ログイン する
クランチについてもっと詳しく

この記事が掲載されているブログ

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

よく一緒に読まれる記事

0件のコメント

ブログ開設 or ログイン してコメントを送ってみよう