Ruby の初心者向けの記事で
変数とは値を入れる箱のようなものです
とか
変数とは名前の付いた箱です
といった記述を非常によく目にします。
しかし,Ruby の場合,変数を箱のアナロジー(類推)で捉えようとすると困ったことになります。
以下のコードを見てみましょう。
a = "Ruby"
b = a
a.upcase!
p a # => "RUBY"
p b # => "RUBY"
1 行目で,ローカル変数 a
に文字列 "Ruby"
を代入しました。
2 行目で,その a
の値をローカル変数 b
に代入しました。
3 行目で,a
の値である文字列オブジェクトを破壊的に大文字化しました。
そして,a
の値と b
の値を表示させました。
どちらも大文字の RUBY
が表示されました。
これは,a
の値と b
の値が同じオブジェクトであることを意味しています。
「同じ」というのは「内容的に同じ」という意味ではありません。b
の値は a
の値そのものということです。
「完璧に同じ姿をした二人の人物」ではなく「同一人物」ということです。
いったい,二つの箱の中に同時に一つの物体が入っている,などということが想像できるでしょうか。
これは箱のアナロジーが破綻していることを意味しています1。
アナロジーというものは,〈よく理解している似たもの〉を持ってきて,その類似性を手がかりにして〈よく知らないもの〉を理解したり推し量ったりすることですね。
このとき,何もかも似ている必要はなくて,違っているところがあっても構いません。しかし,その違っている部分のために理解に支障をきたすのであれば,そのアナロジーは適切ではなかったということになります。
Ruby の変数の箱のアナロジーは混乱を招くと私は考えています。
ではどのようなアナロジーならいいのでしょうか。
私は「名札」を推します。
代入とは「オブジェクトに名札を紐付けること」です。まあ,木の札に名前が書いてあって,そこからひゅるひゅると紐が伸びていてその先に物体が括り付けられている様子でも思い浮かべてください
変数の値とは「名札に紐付いたオブジェクト」です。
一つのオブジェクトにはいくつでも名札を紐付けることができます。
しかし,一つの名札を同時に複数のオブジェクトに紐付けることはできません。
上に掲げたコードは以下のように表現できます。
1 行目:文字列オブジェクト "Ruby"
に名札 a
を紐付けました。
2 行目:名札 a
に紐付いたオブジェクトに名札 b
を紐付けました。
3 行目:名札 a
に紐付いた文字列オブジェクトを破壊的に大文字化しました。
二つの名札には同じオブジェクトが紐付いているので,表示させるオブジェクトをどちらの名札で指定しても,当然同じ結果になります。