Search

検索したいワードを入力してください

2019年04月10日

Rubyで便利なシンボルとは?使い方とメリットを解説

文字列のようで、文字列ではない。Rubyにおけるシンボルオブジェクトとは何なのか、シンボルの性質、使い方、気を付けたい点をご紹介します。Rubyではハッシュなどによく使用されるオブジェクトで、Rubyを使っていれば必ず遭遇します。

Rubyのシンボルとは

Rubyでは、シンボルというオブジェクトを使うことができます。Rubyのリファレンスには、以下のように説明されています。

シンボルは任意の文字列と一対一に対応するオブジェクトです。
文字列の代わりに用いることもできますが、必ずしも文字列と同じ振る舞いをするわけではありません。 同じ内容のシンボルはかならず同一のオブジェクトです。

出典: https://docs.ruby-lang.org/ja/2.5.0/class/Symbol.html |

シンボルは、文字列による表現と対応する、同一性の保証されたオブジェクトです。次のコードで、同じ内容のシンボルは必ず同一のオブジェクトであることを確認できます。

p :a.equal?(:a) # -> true

すなわち、:a というシンボルは、コードの中で何度登場しても同じオブジェクトを指します。

文字列とは

一方、文字列オブジェクトでは、異なるオブジェクトが全く同じ内容を持つことができます。次のコードでは、同じ内容の異なる文字列オブジェクトを比較しています。

p "a".equal?("a") # -> false

レシーバの"a"と引数の"a"は異なるオブジェクトを指しているということです。これが、シンボルと文字列の最大の違いです。

シンボルの特徴

Rubyのシンボルが、使い方によってどのような特徴を表すのか、具体的にご紹介します。シンボルの特徴は端的に言えば、immutable(変更不可能)で高速、省メモリなラベルのようなものです。

hashのキーとして使うシンボル

シンボルの用途で代表的なものは、hashのキーとして利用することです。hashのキーには文字列を使うことも、シンボルを使うこともできます。

h1 = { "train" => "station", "bus" => "stop", "airplane" => "airport" } # 文字列のキー
h2 = { :train => "station", :bus => "stop", :airplane => "airport" } # シンボルのキー
p h1["train"] # -> "station"
p h2[:train] # -> "station"
p h1[:train] # -> nil
p h2["train"] # -> nil

h1は文字列キーを使ったハッシュ、h2はシンボルキーを使ったハッシュです。キーに文字列、シンボルのどちらを使っても同じように動作しますが、キーが文字列のハッシュなのにシンボルキーを検索したり、逆にキーがシンボルのハッシュなのに文字列キーを検索したりしても、nilが返ります。

シンボルと文字列は異なるオブジェクトであり、hash化の方法も異なるからです。これはよく出くわすバグの原因なので、シンボルと文字列の区別を見分けることが必要です。

コロン記号はシンボルの意味

既にサンプルコードをご紹介してきていますが、シンボルを生成するには:を使います。変数名やメソッド名に使えない特殊な文字を使いたい場合は、文字列を''で囲むか、Stringクラスのto_symメソッドを利用します。

s1 = :normal_symbol
s2 = :"special characters like & % #"
s3 = "string to symbol".to_sym

前置コロンと後置コロン

Rubyでのシンボルの定義方法は、基本的には先述のような前置コロンですが、特別なケースとして、ハッシュのキーとしてシンボルを使う場合には、後置コロン記法を使うことができます。後置コロンを使うと、=>記号を省略できるため、記述が簡潔になります。次のコードで、h1とh2は全く同じ内容のハッシュとなります。

h1 = { :train => "station", :bus => "stop", :airplane => "airport" } # 前置コロン
h2 = { train: "station", bus: "stop", airplane: "airport" } # 後置コロン

シンボルはオブジェクトのひとつ

Rubyでは何でもオブジェクトです。シンボルも例外ではなく、Rubyのオブジェクトですので、定義されているメソッドを呼ぶことができますし、定義を追加することさえもできます。

p :abcdef.slice(1..3) # -> "bcd"
p :abcdef[1..3] # -> "bcd"
p :abcdef.upcase # -> :ABCDEF

class Symbol
def first
self[0]
end
end

p :abcdef.first # -> "a"

このように、文字列と同じようなメソッドを呼び出せます。ただし、特異メソッドのnewは使えません。これは、同じシンボルは常に同じオブジェクトであるというシンボルの性質上、必然の仕様です。この点では、文字列よりも数値に近いというのがRubyのシンボルです。

シンボルのメリット

ここまで、シンボルの特徴を見てきました。しかし、ハッシュキーには文字列も使えますし、文字列で使えるメソッドの一部はシンボルにはありませんから、文字列に変換するくらいなら常に文字列を使えば良さそうに見えます。

なぜ、シンボルというクラスが存在するのでしょうか。Rubyでシンボルを使うことのメリットには、主にパフォーマンス面とメンテナンス面での優位性があります。

メモリ消費が少ない

Rubyのシンボルは、コードの中に何度同じシンボルが現れても、同一のオブジェクトです。これはつまり、シンボルの生成は一度だけ行われ、その後は同じオブジェクトが使い回されるということです。

それとは対照的に、文字列オブジェクトはリテラルが現れるたびに新たなオブジェクトが生成されます。全く同じ内容だったとしても、登場した分の文字列オブジェクトが作られます。これは、文字列を変更する予定がない場合、無駄にメモリを消費してしまうことになります。

このように、シンボルのメリットの一つは、省メモリで動作させることができる点です。

可読性が上がる

先述の通り、Rubyではシンボルを使った記法にバリエーションがあり、上手に使い分けることで読みやすくコードを記述することができます。

また、シンボルは常にイミュータブル(変更不可能)なので、破壊的な変更を明示的に防ぐことができます。破壊的な変更はバグを生じる原因となりやすいため、できる限りイミュータブルな性質を持つシンボルを用いることで、メンテナンス性が向上します。

処理が高速になる

Rubyのシンボルは、内部の比較・演算に単なる数値を使っています。そのため、シンボルでは文字列に比べて高速な処理が実現されています。次のコードは、シンボルの配列と文字列の配列でソートに要する処理時間を計測しています。

require 'benchmark'

array1 = [:apple, :orange, :peach]
array2 = ["apple", "orange", "peach"]

t1 = Benchmark.realtime do
for i in 1..10000 do
array1.sort! do |a, b|
case i%2
when 0 then a <=> b
when 1 then b <=> a
end
end
end
end

t2 = Benchmark.realtime do
for i in 1..10000 do
array2.sort! do |a, b|
case i%2
when 0 then a <=> b
when 1 then b <=> a
end
end
end
end

p t1
p t2

環境によりますが、シンボルをソートする時間のほうが2倍以上短くなるはずです。この程度のシンプルな処理では気になるほどではありませんが、巨大な配列やハッシュのソートや演算を伴う場合には、パフォーマンスに差が出てきます。

できるだけシンボルを使う

ここまでご紹介してきたように、Rubyではシンボルを使うことでパフォーマンス、メンテナンスの点で恩恵を受けることができます。一般に、シンボルを用いて問題が無い箇所では、積極的にシンボルを利用することが好まれますので、できるだけシンボルを活用するようにしましょう。

また、文字列とシンボルが混在するとバグの原因にもなります。既存のコードを利用する場合は、この点にも注意する必要があります。シンボルの性質を理解し、パフォーマンス、メンテナンス共に優れたプログラムを作りましょう。

【PR】多くの人がプログラミングを諦めてしまう理由をご存知ですか?



近年プログラミングを勉強する人が増えています。

プログラミング学習者の多くは独学から取り組もうとしますが、だいたい80%ほどは3ヶ月も続かずに諦めてしまいます。早い人は1日目で。

多くの人がプログラミングを独学しようとして諦める理由は、次の3つ。
●モチベーションが維持できない
●エラーの原因・解決方法が分からない
●どう学習すればよいか分からない

TechBoostというプログラミングスクールでは、みんなと一緒にプログラミングをするのでモチベーションの維持ができ、分からないことがあればマンツーマンで教えてくれ、徹底的に研究された初心者向けの教材が揃っています。

TechBoostを卒業後、実際にエンジニアとして転職した方もいるほど。

本気でプログラミングを学びたい方は、一度無料のカウンセリングでご相談ください。プログラミングを嫌いになる前に。

tech boostについて

オーダーメイド型の学習コンテンツを提供する「tech boost」 は、エンジニアのキャリア支援に特化したサービスを複数展開している株式会社Branding Engineerが運営しているプログラミングスクールです。最短3ヶ月間で、未経験から『プログラミングの基礎』、『実際に業務で必要となるスキル』、『今のトレンドとなっている知識』まで学べ、ご希望の方にはプロのキャリアアドバイザーによる就業支援を行うことができます。

tech boost卒業生インタビュー

tech boostの卒業生の声を聞きました。あなたがプログラミングを学びたい理由を、一度考えてみてください。
営業→Javaエンジニア→Rubyエンジニアと転向し、第一志望のFinTech企業で働く山下さん
元営業、ビジネスのわかるエンジニアを目指す菅原さん
サンフランシスコに交換留学し、シリコンバレーのVCでインターン中の梅本さん
予備校の営業から半年でエンジニア転職を果たした小田島さん

tech boostの口コミ



Related