スコーンの開発日記

開発中の学びをまとめていく。

【Ruby】文字列とシンボルの違い

文字列とシンボルの違いがよくわかっていないので整理する。

シンボルとは?

Symbolクラスのレファレンスを見てみる。

docs.ruby-lang.org

Rubyの内部実装では、メソッド名や変数名、定数名、クラス名など の`名前'を整数で管理しています。これは名前を直接文字列として処理するよりも 速度面で有利だからです。そしてその整数をRubyのコード上で表現したものがシンボルです。

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

名前を管理するという役割上、シンボルと文字列は一対一に対応します。 また、文字列と違い、immutable (変更不可)であり、同値ならば必ず同一です。

メソッド名や変数名

Rubyの内部実装では、メソッド名や変数名、定数名、クラス名など の`名前'を整数で管理しています。(中略)そしてその整数をRubyのコード上で表現したものがシンボルです。

試してみる。

class Foo
  def initialize
  end

  def do_something
  end
end

bar = 'bar'
buzz = 0

p Symbol.all_symbols
# -> [(デフォルトで持っているシンボル?), :Foo, :do_something, :bar, :buzz]

なるほど、確かにシンボルができている。

シンボルは同値ならば同一オブジェクト

名前を管理するという役割上、シンボルと文字列は一対一に対応します。 また、文字列と違い、immutable (変更不可)であり、同値ならば必ず同一です。

オブジェクトIDを返すobject_idメソッドで確認してみる。

ref.xaio.jp

文字列

'foo'.object_id
=> 70365246172220

'foo'.object_id
=> 70365246156560

'foo'.object_id
=> 70365246136960

シンボル

:foo.object_id
=> 1246748

:foo.object_id
=> 1246748

:foo.object_id
=> 1246748

たしかに、文字列だと毎回オブジェクトIDが変わるがシンボルだと変わらない。

ハッシュのキー

シンボルはハッシュのキーとしてよく使うのだが、文字列とは異なるオブジェクトであることを確認。

# キーが文字列のとき
hash1 = {'foo'=> 1, 'bar'=> 2}
=> {"foo"=>1, "bar"=>2}
hash1['foo']
=> 1
hash1[:foo]
=> nil

# キーがシンボルのとき
hash2 = {foo: 1, bar: 2}
=> {:foo=>1, :bar=>2}
hash2['foo']
=> nil
hash2[:foo]
=> 1

references