【Ruby】シンボルの書き方と使い方の基本

作成日: 更新日:

開発環境

  • Ruby version: ruby 3.1.2

Rubyのシンボルとは

Rubyのシンボルとは、任意の文字列と一対一に対応するシンボルクラスのオブジェクトです。 シンボルはソース上では文字列のように見えますが、Rubyの内部では「整数」として管理されているため、immutable (変更不可)なオブジェクトで同値ならば必ず同一となります。 公式リファレンス:https://docs.ruby-lang.org/ja/latest/class/Symbol.html

Rubyのシンボルの書き方

Rubyのシンボルの書き方をご紹介します。

1"symbol" #文字列
2:symbol  #シンボル

文字列は「'(シングルクォート)」、または「"(ダブルクォート)」で囲みますが、シンボルは「:(コロン)」から始まります。

Rubyのシンボルの使い方

Rubyのシンボルのよくあるパターンをサンプルコードを用いて使い方の解説をしていきます。

配列でシンボルを使うパターン

配列でシンボルを使うパターンです。

1# 配列でstringクラスを使用する場合
2string_array = ["obj1", "obj2", "obj3", "obj4", "obj5"]
3p string_array[0] # "obj1"
4
5# 配列でsymbolクラスを使用する場合
6symbol_array = [:obj1, :obj2, :obj3, :obj4, :obj5]
7p symbol_array[0] # :obj1

取り出される値はそれぞれstringクラスとsymbolクラスになります。

ハッシュでシンボルを使うパターン

ハッシュでシンボルを使うパターンです。

1# ハッシュでstringクラスを使用する場合
2string_hash  = { "key1" => "value1", "key2" => "value2", "key3" => "value3" }
3p string_hash["key1"]

ハッシュのキーにstringクラスを使用している場合、値を取り出すときのキー指定もstringクラスを使用します。

1# ハッシュでsymbolクラスを使用する場合(キーが前置コロン)
2symbol_hash1 = { :key1 => :value1, :key2 => :value2, :key3 => :value3 }
3p symbol_hash1[:key1]

ハッシュのキーに前置コロンのsymbolクラスを使用している場合、値を取り出すときのキー指定も前置コロンのsymbolクラスを使用します。

1# ハッシュでsymbolクラスを使用する場合(キーが後置コロン)
2symbol_hash2 = { key1: :value1, key2: :value2, key3: :value3 }
3p symbol_hash2[:key1]

ハッシュのキーに後置コロンを使用した場合は「=>(ダブルアロー)」を省略して記述しますが、値を取り出すときのキー指定は前置コロンのsymbolクラスを使用します。

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

Rubyのシンボルと文字列の違いは大きく4つあります。

シンボルと文字列のクラスの違い

シンボルはSymbolクラスとなり、文字列はStringクラスとなります。

1p "symbol".class # String
2p :symbol.class  # Symbol

シンボルと文字列の破壊的な変更の違い

文字列は破壊的な変更は可能ですが、シンボルは破壊的な変更は不可能です。

1# 文字列は破壊的な変更は可能
2string = "ruby"
3p string.upcase! # "RUBY"
4
5# シンボルは破壊的な変更は不可能
6symbol = :ruby
7p symbol.upcase! # undefined method `upcase!' for :ruby:Symbol

シンボルと文字列のオブジェクトの違い

シンボルは同じ内容であれば必ず同一オブジェクトとなりますが、文字列は同じ内容であっても同一のオブジェクトにはなりません。

1p :ruby.object_id   #=> 727388
2p :ruby.object_id   #=> 727388
3
4p "ruby".object_id  #=> 60
5p "ruby".object_id  #=> 80

シンボルは同一のオブジェクトになるため、メモリの使用効率が良いということになります。

シンボルと文字列の処理速度の違い

シンボルは内部で整数として管理されるため、文字列と比べて高速に処理できます。

1require 'benchmark'
2include Benchmark
3
4# シンボルを使ったメソッド
5def processing_speed_symbol(num)
6    obj1 = :ruby
7    obj2 = :ruby
8    num.times do
9        obj1 == obj2
10    end
11end
12
13# 文字列を使ったメソッド
14def processing_speed_string(num)
15    obj1 = "ruby"
16    obj2 = "ruby"
17    num.times do
18        obj1 == obj2
19    end
20end
21
22# 計測結果のメソッド
23Benchmark.benchmark(CAPTION, 7, FORMAT) do |x|
24    x.report("symbol"){ processing_speed_symbol(1000000) }
25    x.report("string"){ processing_speed_string(1000000) }
26end

上記はobj1とobj2を比較する処理にシンボルを使った場合と文字列を使った場合のメソッドです。 そして、下記が実行結果です。

1user     system      total        real
2symbol    0.031000   0.000000   0.031000 (  0.039583)
3string    0.047000   0.000000   0.047000 (  0.041310)

文字列よりシンボルのほうが処理速度が速いことがわかったかと思います。

おわりに

Rubyのシンボルの使い方を解説してきました。 シンボルはsymbolクラス、文字列はstringクラスになるため、オブジェクトのクラスが異なれば使用できるメソッドも違います。 特に連想配列であるハッシュでは必ずと言ってよいほどシンボルを使用するため、最低でも前置コロンと後置コロンの使い方は知っておきましょう。

【Ruby】シンボルの書き方と使い方の基本 | いっしー@Webエンジニア