【Ruby】"x = 1" は "x に 1 を代入する" ではない!

変数とはそもそも何なのか

 

という疑問から表題に行き着き、さらには

 

puts "Hello World" は "Hello World" つまり右に書いてあることを出力せよ!というものではないというところにまで行き着きました。

 

まぁ、わかりやすい話、puts は、右に書いてあるものを単に出力せよ!ということであるなら。適当な英数字を入れればそれら全て出力されるということである。

 

だが、実際に出力されるのは、数字ないしは文字列のみであり、変数は宣言されていない限り出力されない。

 

つまり、puts 〜 は、〜というオブジェクトを出力せよという命令文であり、オブジェクト以外はエラーとなる。

 

Ruby では全てオブジェクトであり、変数もオブジェクトである!

 

なんてなのは真っ赤な嘘だ!

 

ちなみに puts の右側に書けば、その時点でオブジェクトは生成されるっぽいので "Hello World" と書けば、その時点である id を持ったオブジェクトが生成され、出力される。

 

という仕組みのようである。

 

オブジェクトがその時点で生成されてなく、ただの英数字としての認識であるならば、宣言されていない変数も、出力されて然るべきなので、おそらく間違っていない。

 

ちなみに { } や [ ] もオブジェクトなので出力される。もちろん空なので表示自体は何もないのだが、エラーにはならない。

 

いちいち items  = { } や、names = [ ] としなくても作れることは作れる。

items や names は変数だ。

 

では変数とは何なのかという問いに戻る。

 

そもそもオブジェクトを作るのに変数は必要ない

 

puts でもオブジェクトは作成されたし、数字も"文字列"も入力されればオブジェクトとして生成される。(若干嘘あり。ある桁数までの数字は最初から id が割り振られている)

 

ただ、オブジェクトを扱うのに変数が必要なのである

 

a = "aaa" 

 

というのを見てみることにする。

 

この場合、生成されたオブジェクトは右辺の "aaa"である。

 

そして、変数 a はただの識別子である。それを見ていくためは、オブジェクトIDを調べてみれば良い。

 

a.object_id
=> 70187710432980

 

ここで

 

a = a + "aaa"

 

を見ていく。

仮に、 =が代入であるのであれば、変数 a のオブジェクトIDは変わらないはずである。変数は入れ物であるという説明を聞いたりもするが、中身が変わっただけで箱が変わらないというのであればIDが変わるのはおかしい。

 

a.object_id
=> 70187710384260

 

違いますね。

 

つまり、代入ではない。

 

=の右辺において、a + "aaa" という新しいオブジェクトが生成されたのである。

 

そのため、オブジェクトIDが変わった。変わったというより、違うものであるので違うIDが割り振られて当然なのである。

 

では変数とは何なのかという問いであるが

 

オブジェクトはバンバン作れる!が、作っただけではその場限りになってしまう。

 

そこで

 

オブジェクトを扱うために変数が存在している。

 

変数 = オブジェクト

 

は、あるオブジェクトをある一つの変数として扱い、いつでも使えるようにした。

 

ということである。

 

 

ようである。。。

 

まだまだ勉強浅いのでこの辺で。

 

 

余談ですが。数字にはもともとidが振られていると話しました。

0 は id = 1、1 は id = 3、2 は id = 5 ・・・

 

id =  2n + 1 のようです。

 

上限は

 

irb(main):008:0> 10000000000000.object_id
=> 20000000000001
irb(main):009:0> 100000000000000.object_id
=> 200000000000001
irb(main):010:0> 1000000000000000.object_id
=> 2000000000000001
irb(main):011:0> 10000000000000000.object_id
=> 20000000000000001
irb(main):012:0> 100000000000000000.object_id
=> 200000000000000001
irb(main):013:0> 1000000000000000000.object_id
=> 2000000000000000001
irb(main):014:0> 10000000000000000000.object_id
=> 70330865618720

 

このあたりのようです。