シンボルとは
公式ドキュメントでは次のように説明しています。
Ruby 2.6.0 リファレンスマニュアル
シンボルを表すクラス。シンボルは任意の文字列と一対一に対応するオブジェクトです。
文字列の代わりに用いることもできますが、必ずしも文字列と同じ振る舞いをするわけではありません。同じ内容のシンボルは必ず同一のオブジェクトです。Rubyの内部実装では、メソッド名や変数名、定数名、クラス名など の`名前'を整数で管理しています。これは名前を直接文字列として処理するよりも 速度面で有利だからです。そしてその整数をRubyのコード上で表現したものがシンボルです。
シンボルは、ソース上では文字列のように見え、内部では整数として扱われる、両者を仲立ちするような存在です。
名前を管理するという役割上、シンボルと文字列は一対一に対応します。 また、文字列と違い、immutable (変更不可)であり、同値ならば必ず同一です。
文字列と似ているオブジェクトで、ソース上では文字列のように見えているが、内部的には整数として扱われている。ということですかね。
シンボルの書き方
文字列は'Ruby'
のように'
(シングルクォート)もしくは"
(ダブルクォート)で囲むが、シンボルは:Ruby
というように:
(コロン)から始まる。
# シンボル
:Ruby
# 文字列
'Ruby'
シンボルと文字列の違い
SymbolクラスとStringクラス
シンボルはSymbol
クラスのオブジェクトで、文字列はString
クラスのオブジェクトになる。
puts :Ruby.class #=> Symbol
puts 'Ruby'.class #=> String
処理速度
シンボルは内部で整数として管理されるため、文字列と比べて高速に処理できる。
# シンボルの方が早く処理できる
:Ruby == :Ruby
'Ruby' == 'Ruby'
同じシンボルであればオブジェクトも同じ
文字列と違い同じ内容のシンボルは必ず同一のオブジェクトとなり、オブジェクトの数が増えないためメモリの使用効率がよくなる。
puts :Ruby.object_id #=> 989668
puts :Ruby.object_id #=> 989668
puts :Ruby.object_id #=> 989668
puts 'Ruby'.object_id #=> 70270585805660
puts 'Ruby'.object_id #=> 70270585805600
puts 'Ruby'.object_id #=> 70270585805540
シンボルはimmutable(イミュータブル)
シンボルはimmutable(変更不可)なオブジェクトのため、文字列のように破壊的な変更ができない。
なので、「変更できない名前をつける」という用途に向いている。
# シンボルはimmutableなので、破壊的な変更は不可能
symbol = :Ruby
puts symbol.upcase!
#=> undefined method `upcase!' for :Ruby:Symbol (NoMethodError)
# 文字列は破壊的な変更が可能
string = 'Ruby'
puts string.upcase! #=> RUBY
シンボルのまとめと主な用途
まとめ
- 文字列とは違うが似ているため、プログラマにとって理解しやすい。
- 内部で整数として扱っているため、文字列に比べて処理速度が速い。
- 同じ内容のシンボルは必ず同一のオブジェクトとなるため、メモリの使用効率が良い。
- immutableなので、勝手に値を変えられない。
主な用途
- ハッシュのキー
- クラス名/メソッド名/変数名/定数名
- ステータス名
これらは文字列自体がデータではないのでシンボルを使うと良い。
逆に文字列は「氏名」や「住所」など、文字列自体がデータであるときに使う。
関連記事
ハッシュの基本【Ruby超入門】