工藤探偵事務所

Resarch and Investigation

ルビー3分クッキング 第十一回「変数の中身」の巻

kudo-shunsaku2008-04-22



3分間で覚える Ruby のトピックスです。
でも、本家同様に実際には10分程度掛かります。

大事なのは小さな積み重ねと継続する才能ですね。
一番の怠け者の俺が言うのも変ですけどね。

第十一回は、「変数の中身」の巻です。


ちなみに思いつきでここまで進めてきましたので、ここいらで前号まで何を書いたのか整理しておきます。

第一回「標準出力への印字」の巻
第二回「文字列のつくり方」の巻
第三回「文字列は配列?」の巻
第四回「配列がスタックに」の巻
第五回「ハッシュをつくろう」の巻
第六回「日本語を表示する」の巻
第七回「繰り返しの不思議」の巻
第八回「繰り返しの不思議の繰り返し」の巻
第九回「選択は幻想」の巻
第十回「反復からの卒業」の巻

お題目にしたのは自分が勉強していて理解し辛いところを挙げてきた様な気がします。
これからも、その時々の流れ、つまり思いつきで進めて参ります。
話が彼方此方に跳ぶかと想いますが、ご興味あればお付き合い下さいませ。


今回は「変数」についてお話したいと想います。

以前の記事で配列についてご紹介したときに「参照(オブジェクト・リファレンス)を保持しているんだよ」といった話が出てきましたが、この話についてです。配列だけの話ではなく、 Ruby の変数自体がそのような(?)仕組みになっているそうなのです。

では変数が実際にどのような仕組みかを探ってみましょう。

ファイル名は、"object_reference.rb" などとして下さい。

# メニューとしてボンゴレ・ビアンコを用意しました。
spaghetti_01 = "Spaghetti alle Vongole Bianco"
spaghetti_02 = spaghetti_01

p spaghetti_01
p spaghetti_02

puts

# 白ワインから赤ワインに変更します。
spaghetti_01["Bianco"] = "Rosso"

p spaghetti_01
p spaghetti_02

puts

# 参照しているスパゲッティを確認します。
p spaghetti_01.object_id
p spaghetti_02.object_id

実行時、コンソール画面。

C:\rubycode\3minutes2cooking>ruby object_reference.rb
"Spaghetti alle Vongole Bianco"
"Spaghetti alle Vongole Bianco"

"Spaghetti alle Vongole Rosso"
"Spaghetti alle Vongole Rosso"

22922640
22922640

C:\rubycode\3minutes2cooking>

何をしているのか?お分かりになりますでしょうか?

まず文字列(Stringオブジェクト) を変数 "spaghetti_01" に代入します。
変数 "spaghetti_02" に 変数 "spaghetti_01" に代入します。

そして二つの変数を印字すると同じスパゲッティが出てきますね。
これは当たり前ですかね?

次に、変数 "spaghetti_01" の指している文字列の一部分を変更します。
ボンゴレ・ビアンコ」じゃなくて「ボンゴレ・ロッソ」にメニューを変えます。

その後に再度、二つの変数を印字すると二つとも(!)「ボンゴレ・ロッソ」になっていることが判ります。

つまりRuby の場合には、変数にはスパゲッティ(文字列)そのもの(オブジェクト)が入る訳ではなくて、スパゲッティを指し示していると言えます。つまり参照しているのです。ですから、二つの変数が同じスパゲッティ(文字列)を指しているために、双方が変更されたように見えたのです。要するに同じスパゲッティ(文字列)なのですから、当たり前ですけど。

更にこれを確かにするために、"object_id" というメソッドがあります。これは指し示しているオブジェクトを整数で表現して返してくれます。オブジェクトの番号です。

これを実行すると同じオブジェクトの番号であり、つまり同じオブジェクトを示していることが判ります。

ちょっと判り難いですよね?もう一回確認してみましょう。

先ほどは、は一皿のスパゲッティを二人(二つの変数)で見ていました。
今度は、二皿のスパゲッティをそれぞれに用意して同じことをしましょう。

先ほどのソースコードを変更します。

# メニューとしてボンゴレ・ビアンコを用意しました。
spaghetti_01 = "Spaghetti alle Vongole Bianco"

# もう一皿別に、ボンゴレ・ロッソを用意します。
spaghetti_02 = "Spaghetti alle Vongole Rosso"

p spaghetti_01
p spaghetti_02

# 参照しているスパゲッティを確認します。
p spaghetti_01.object_id
p spaghetti_02.object_id

puts

# 白ワインから赤ワインに変更します。
spaghetti_01["Bianco"] = "Rosso"

p spaghetti_01
p spaghetti_02

# 念のためもう一度スパゲッティを確認します。
p spaghetti_01.object_id
p spaghetti_02.object_id

実行時、コンソール画面。

C:\rubycode\3minutes2cooking>ruby object_reference.rb
"Spaghetti alle Vongole Bianco"
"Spaghetti alle Vongole Rosso"
22921630
22921620

"Spaghetti alle Vongole Rosso"
"Spaghetti alle Vongole Bianco"
22921630
22921620

C:\rubycode\3minutes2cooking>

わかりましたでしょうか?

今度は別々のスパゲティ(文字列)をそれぞれに用意しました。
"object_id" で番号を確認すると、違うスパゲティ(文字列)を指していることが確認できます。

そして、先ほどと同様に「ボンゴレ・ビアンコ」から「ボンゴレ・ロッソ」にメニューを変えます。ついでにもう一つのお皿も「ボンゴレ・ロッソ」から「ボンゴレ・ビアンコ」に変えます。

ちゃんとそれぞれのメニューが指示通りに変わっています。別々のスパゲティをそれぞれで変えたので先ほどのように片方の変更が相互に影響するようなことはありませんね。当たり前といえば当たり前ですよね。

では念のために配列でもやってみましょう。

先ほどのソースコードを変更します。

# 配列でボンゴレ・ビアンコを用意しました。
spaghetti_01 = ["Spaghetti", "alle", "Vongole", "Bianco"]
# 同じスパゲティです。
spaghetti_02 = spaghetti_01

p spaghetti_01
p spaghetti_02

puts

# 白ワインから赤ワインに変更します。
spaghetti_01[3] = "Rosso"

p spaghetti_01
p spaghetti_02

# 参照しているスパゲッティを確認します。
p spaghetti_01.object_id
p spaghetti_02.object_id


puts
puts

# もう一度。今度は別々に用意します。
spaghetti_01 = ["Spaghetti", "alle", "Vongole", "Bianco"]
spaghetti_02 = ["Spaghetti", "alle", "Vongole", "Bianco"]

p spaghetti_01
p spaghetti_02

puts

# 白ワインから赤ワインに変更します。
spaghetti_01[3] = "Rosso"

p spaghetti_01
p spaghetti_02

# 参照しているスパゲッティを確認します。
p spaghetti_01.object_id
p spaghetti_02.object_id

実行時、コンソール画面。

C:\rubycode\3minutes2cooking>ruby object_reference.rb
["Spaghetti", "alle", "Vongole", "Bianco"]
["Spaghetti", "alle", "Vongole", "Bianco"]

["Spaghetti", "alle", "Vongole", "Rosso"]
["Spaghetti", "alle", "Vongole", "Rosso"]
22918560
22918560


["Spaghetti", "alle", "Vongole", "Bianco"]
["Spaghetti", "alle", "Vongole", "Bianco"]

["Spaghetti", "alle", "Vongole", "Rosso"]
["Spaghetti", "alle", "Vongole", "Bianco"]
22918220
22918160

C:\rubycode\3minutes2cooking>

配列を変数に入れても文字列でやったことと同様であることが、確認出来ましたね。

今回は「変数」についてお話しました。「変数」はオブジェクトを指し示しているのであって、オブジェクトそのものが変数に入っているのではないことがお分かり頂けたと想います。

Ruby の「変数」と他の言語(C言語Java言語など)の「変数」とは所作が異なります。ご注意下さいませ。



「スイッチョ♪スイッチョ♪出かけます。♪」

今日はここまで。次回をお楽しみに。