Rubyの変数に他の変数を代入した時の関係(僕的には意外だったRuby変数の考え方)


Rubyの変数とは

簡単に言うと,オブジェクトの入れ物です.
<訂正:2018/11/2>
オブジェクトに繋がるヒモ付きの名札のようなイメージです.つまり,変数を使って処理すると言う場合は変数に繋がれているオブジェクト自体に処理を行うと言うことです.

僕は指摘を受けるまで,Rubyにおける以下のコードを変数に値を代入すると言っていましたが,正確には変数に紐付けされたオブジェクトに値を代入すると言った方がいいのかもしれませんね.

argument = 1000
argument = 2000

ちなみに追記後のこの項目だけで,この記事の本質部分は説明できてることになりました.めでたしめでたし

もっとわかりやすい説明をこの記事のコメント欄にて<@scivola 様>が行ってくれていますので,そちらもご覧ください,

Rubyの整数型や配列型などの型指定とは

IntクラスやArrayクラス等がある中でどのクラスのインスタンスを作成するかを決めると言うことです.

インスタンスとは

クラスが設計図だとしたら,インスタンスは完成品かな.

ここで本題

Rubyで以下のようにコードを書くとどうなるのか.

nums = [0, 1, 2, 3, 4] 
nums_clone = nums
nums[2] = 222
p nums_clone

結果は以下の通り.

[0, 1, 222, 3, 4] 

ここで疑問が生じました.

どうしてnumsの要素を変更したのにnums_cloneの値も変更されているの??

調べてみると,どうも一つのオブジェクトに複数の変数で紐付けすることが可能みたいですね.そこでさらに疑問.

変数に紐付けされたオブジェクトが持つ値のみを他の変数に代入したい時はどうするの??

これはちょっと日本語が難しいのでコードで例をあげると.

father_names = ['tanaka', 'ichiro'] # お父さんの名前
child_names = father_names # 息子の名前登録の下準備
child_names[1] = 'kotaro' # 苗字はそのままで名前のみを変えたい
p father_names # ['tanaka', 'ichiro']にしたいけど今は['tanaka', 'kotaro']
p child_names # ['tanaka', 'kotaro']

こんな感じ.
これは意図することと違うので以下のコードのように.cloneを使用する.

father_names = ['tanaka', 'ichiro'] 
child_names = father_names.clone # .cloneを追加
child_names[1] = 'kotaro' 
p father_names # ['tanaka', 'ichiro']
p child_names # ['tanaka', 'kotaro']

以上です.

まとめ

他の言語と違って,Rubyは数字から文字まで色々なものがオブジェクト(クラス)です.つまり変数に他の変数の値を代入しようとして

変数(a) = 変数(b)

なんて書くと,変数(b)に紐付けされたオブジェクトが変数(a)に繋がっちゃうので,片方の変更がもう片方にも反映されちゃうよ.
つらみ