RubyのSymbol
Rubyを最初学んだとき、SymbolとStringの違いが解って無くて、なら全部StringでいいやとSymbolを全く使わなかった時期がありました。今は意図的に使い分けるようにしています。Lost-Season: Rubyのシンボル で疑問点が上がっていたので、初心者向けにSymbolについて説明してみます。
まず使い道ですが、文字の定義を明確にしたいときに使うことが多いです。たとえばhashのkeyだったり、アクセサの引数で渡すインスタンス変数名だったり、alias_methodの引数で渡すメソッド名だったりと、文字に意味づけしたい時に使えます。このようなときにSymbolを使うことによって、ソースがすっきりして可視性が上がります。
また、symbolを使うと速度が向上します。これは、'a' と書くと毎回Stringの'a'を生成しコストが発生しますが、:aと書くと初回にしかコストが発生しません*1。比較も高速に行えます。
ただ、Hashのkeyとして使うとき、人によっては
hash = {:a => 'foo', :b => 'bar'}
と書いたり、
hash = {'a' => 'foo', 'b' => 'bar'}
と書いたりし、keyがsymbolかstringか解らなくて結局の所ソースを実際に確かめるケースが発生します。Railsではそれを取り除くために、active_supportで定義されているHashWithIndifferentAccessクラスを使い回避しています。これはHashのkeyがsymbolだった場合はstringにキャストされ、symbolでもstringでもvalueにアクセスできるようになっています。これで
url_for :controller => 'foo', :action => 'bar'
url_for 'controller' => 'foo', 'action' => 'bar'
とHashのkeyがstring, symbolどちらでも利用することができます。しかしsymbolからstringへのキャストを毎回するため、速度的には遅くなってしまいます*2が、使いやすさ優先の考え方なのでしょう。
*1: 'a'.equal? 'a' はfalseだが:a.equal? :aはtrue
*2:ベンチマークを取ってみたところ、2倍強差(でも10万回ループで0.275367秒 => 0.664770秒 だけど)