せかいや

いまいるここを、おもしろく http://sekai-in-the-box.appspot.com/

【Ruby】パーフェクトRuby 学習感想文 ~余談:シンボルって何?

パーフェクトRubyを読んで、まだ分かっていないところを、改めて振り返ります。

 
(参考・経緯など)
パーフェクトRuby 学習感想文 ~はじめに

分かっていないところ

Bundle
シンボル

です。
Bundleは今朝見たので、ここではシンボルについて取り上げます。


シンボルって何?

「シンボルは文字列に似ています」

P61にはこう書いてある↓

シンボルは文字列に似ていますが、読み書きのし易さから「attr_accessor :length」のように識別子やキーワード的な単語を表現するのに適しています。

って。。。
説明が全部で4行しかないので、
これで分かったらスーパーマンやろ・・・

「シンボルは文字列に似ていますが」って。
似ています『が』、何なんだ。気になるよ!

例に載っているものも、良く意味が分からない↓

:ruby   #=> :ruby


 

公式ドキュメントを読む

シンボルは、ソース上では文字列のように見え、内部では整数として扱われる、両者を仲立ちするような存在です。

なんだー?? 確認してみよう。

p "hh" == "hh"
p "abc".equal?("abc")
p :abc.equal?(:abc) 

p "abc".object_id
p "abc".object_id

p :abc.object_id
p :abc.object_id

p 100.object_id
p 100.object_id

■実行結果

true
false
true
23935152
23934972
238760
238760
201
201

なるほど。


シンボルについて解説しているサイトがあったので、覗いてみる。

 

his_name = 'Fox'
このようにCharlieに割り当てた変数his_nameをFoxに割り当て直すと、元のCharlieオブジェクトからはhis_nameの名札が外れる。結果ユーザはCharlieオブジェクトに対するアクセス手段を失う。Charlieオブジェクトのその後を知っているのは、Rubyオペレータのみとなりそのようなオブジェクトは彼が後に破棄する。

http://melborne.github.io/2008/08/02/Ruby/

なるほど!ここら辺はJavaガーベッジコレクションの勉強のときに学んだことだ。

この人もobject_id を使って、Ruby空間での同一性を確かめてる。
この方法で問題なさそうだ。
 ⇒公式ガイドでは、object_idを使った同一性は、全くサンプルとして記載されていない(みたことない)から、この判断方法で良いかなってちょっと不安に思ってたんだよね。


文字列オブジェクトだとどんな不都合があるか

検証1

info = "name"
hoge = { info => 'AAA' }
p hoge[info]

info = "kokuseki"
nanika = "name"

p hoge[info]
p hoge[nanika]

■実行結果

"AAA"
nil
"AAA"

この例だと、"info"という箱に入った値、
つまり"name"をキーにしてAAAを格納している。
"info"はただの箱の名前であって、「infoの箱で入れた」事が本質ではない。
だから、infoの箱の中身が変わると値が取り出せない(nil)し、
別の箱の名前で値を取り出すことも出来る。


 

検証2

一つのRuby空間には、
同じ値を持つが、異なる文字列オブジェクトが存在できる

hoge1 = { "name" => 'BBB' }
var1 = "name"
var2 = "name"
p var1.object_id
p var2.object_id
p hoge1[var1]
p hoge1[var2]

■実行結果

23867892
23867880
"BBB"
"BBB"


 

検証3

シンボルは数値と同じで、Ruby空間での存在は唯一

hoge2 = {:name => "CCC"}
boo = :name

p :name.object_id
p boo.object_id
p hoge2[:name]
p hoge2[boo]

■実行結果

40424
40424
"CCC"
"CCC"


分かってきたぞ。
でも言葉で説明しようとするとまだまだ難しい。

このブログで紹介されていた初めてのRuby
って本がすごく面白そう。
次はこれを読もう。