💎

RubyのSymbolオブジェクトについて解説

2021/03/30に公開

Symbol オブジェクトとは?

シンボルは任意の文字列と一対一に対応するオブジェクトです。
by 公式

文字列との違いは?

まず、コロン「:」を文字列の前につけて symbol object を生成します。

irb(main):001:0> :name
=> :name
irb(main):002:0> :name.class
=> Symbol

一見、文字列と同じようにみえますが ruby は symbol object を 整数 として扱います。
これは完全に内部的な話となりますが、symbol は文字列と違い整数として処理される分、高速に処理が行われます。

symbol は何がよいの?

例えば中身が同じ文字列を生成したとき、
String object では例え中身が同じでも別な object を生成することになりますが
Symbol object では同じ object を指すことになるため、メモリの消費が抑えられます。

String での例をみてみます。

irb(main):014:0> string1 = 'String'
=> "String"
irb(main):015:0> string1.object_id
=> 180
irb(main):016:0> string2 = 'String'
=> "String"
irb(main):017:0> string2.object_id
=> 200

実体として object ID をみてみると、それぞれ違うものを指し示していますね。

それに対し、symbol では中身が同じ object であれば同じ object ID を指す、
つまり実体としては同じものを指しているのです。

irb(main):021:0> symbol1 = :String
irb(main):021:0> symbol1 = :String
=> :String
irb(main):022:0> symbol1.object_id
=> 91428
irb(main):023:0> symbol2 = :String
=> :String
irb(main):024:0> symbol2.object_id
=> 91428

この仕様により、新しい Symbol object を生成しても作られるオブジェクトの実体は一つなので
結果としてメモリの消費を抑えることができるのです。

symbol の使用用途

symbol は hash オブジェクトの key として使用されることが多いです。
(hash: key と値の組み合わせを保持するオブジェクト)

irb(main):025:0> { name: 'Masuyama', age: 29 }
=> {:name=>"Masuyama", :age=>29}

上記の hash の例では name という key に対して Masuyama という値を持ち、
age という key に対して 29 という値を持つデータを表現できます。

Ruby では key となる文字列にコロン「:」をつける記法がよく登場しますが、
この時の key は symbol として扱われることになります。

データベースのカラム名をイメージすると分かりやすいのですが、
key 自体は様々なデータから参照されるものですので
データが作成される都度、新しいオブジェクトを生成するよりも同じオブジェクトを使った方が効率が良いですよね。
そのため、hash の key として symbol object がよく使われるのです。

Discussion