Ruby のシンボルについて [Ruby]
いまいちよく分かっていなかった Ruby のシンボルについて少し調べた。
「文字列とどう違うの?」という疑問の答えはこういうことらしい。
irb(main):001:0> "abc" == "abc"
=> true
irb(main):002:0> "abc".equal?("abc")
=> false
irb(main):003:0> :abc == :abc
=> true
irb(main):004:0> :abc.equal?(:abc)
=> true
== は表現を比較し、equal? はオブジェクトの同一性を比較する。文字列は同じ表現が同一の実体とは限らないけど同じ名前のシンボルは同じ実体である。
Ruby でシンボルが使われる典型的な例はハッシュのキー。
irb(main):010:0> {:key1 => "one", :key2 => "two"}
=> {:key1=>"one", :key2=>"two"}
でも文字列も普通に使えるし、キーの同一性についての振る舞いが違うということでもないようだ(ハッシュのキーはオブジェクトIDではなく表現で同一性が判断されているようだ)。ハッシュのキーによく使われるのはシンボルの内部表現が整数なので効率がいいというのが理由。
irb(main):012:0> {:key1 => "one", :key1 => "two"}
=> {:key1=>"two"}
irb(main):013:0> {"key1" => "one", "key1" => "two"}
=> {"key1"=>"two"}
リファレンスを眺めた限りでは Lisp の gensym のように既存のシンボルと重複しないシンボルを生成してくれるものはないようだ。
あと Ruby 内部では変数名をシンボルとして管理しているそうだけど、その変数テーブルへのアクセスの方法とかそういう辺りはよく分からなかった。できないのかもしれない。
ちなみに唐突にシンボルについて調べたのは、前回記事 [1] で思ったことの続きで、既存の変数と重複しない変数名を一時的に生成できれば「文脈に関わらずブロックローカルになる変数」を苦しいやりかたで実現できるかも、とちょっと思いついたという理由。まあ可能だったとしてもそんなイディオムは使いたくないと思うけど。
[1] http://blog.so-net.ne.jp/rainyday/2007-02-13
コメント 0