Rubyではシンボルという特殊なオブジェクトを使えます。シンボルは、文字列のオブジェクトなど、他のオブジェクトとセットで使われるオブジェクトで、シンボル単体として作ることはできません。そして、シンボルが使える機能も限られています。今回はRubyにおけるシンボルの基本とその使い方を紹介します。
Rubyにおけるシンボルとは
他の人が書いたRubyのプログラムで「:」を見かけたら、それはシンボルかもしれません。まずは、そもそもRubyのシンボルをよく知らないという方のために、その基本について紹介します。
シンボルの特徴
Rubyのプログラムで使われるデータ、例えば変数や数字、文字列などは全てオブジェクトです。オブジェクトだからこそ、その中に定義されたメソッドを利用できます。
ただし、プログラムで使われるデータの全てが、Stinrgクラスのようなオブジェクトとは限りません。今回紹介するシンボルは、文字列と1対1に対応するラベルのようなオブジェクトです。
そのためシンボルを使用する場合、シンボルに対応する文字列などが存在しなければなりません。そしてシンボルをアクセスすると、対応している文字列などが参照されます。
シンボルオブジェクトの基本
先ほど紹介したようにRubyにおけるシンボルとは、任意の文字列などと1対1に対応するオブジェクトです。そのため、Rubyのプログラムでシンボルを利用するには、対応する文字列などのオブジェクトがなければなりません。
そしてシンボルを説明するのに最も解りやすいのはRubyではハッシュです。ハッシュでは、キーと文字列が1対1に対応しており、定義する際キーと文字列を「=>」で接続します。そして、プログラムの中でシンボルを使うことで、それに対応した文字列が利用されます。
ハッシュの例
{ :key => "value" }
この例では、ハッシュのキーに当たる「:key」がシンボルであり、値の「value」がそれに対応した文字列です。
シンボルに使える文字
シンボルは、先ほど紹介したように文字列の左側にコロン(:)を付けて記述します。なおシンボルに使える文字は文字列に使える文字であり、日本語が使えるrubyではひらがなや漢字も使えます。
ただし数字から始まるシンボルは作れません。また文字列に使えない記号を含めることができないので注意してください。
エラーになるシンボルの例
:1-1 => "第1章の1項" :#label => "検索文字列"
シンボルは、Rubyの内部では文字列をハッシュ関数で変換した数字として扱われます。そのため、ハッシュ関数で計算できない文字はシンボルとして使用できません。
シンボルの用途
先ほど紹介したようにシンボルは、文字列と1対1に対応するものです。ただし、Rubyのシンボルの用途は限らており、プログラムのどこででも使える訳ではありません。次にシンボルの4つの用途について簡単に紹介します。
シンボルの用途
- ハッシュのキー
- アクセサの引数で渡すインスタンス変数名
- sendメソッド引数で渡すメソッド名
- enumで指定するカラム名
ハッシュのキー
Rubyのハッシュとは他のプログラミング言語の連想配列のことで、配列の添え字に数字ではなくシンボルを指定して利用します。
ハッシュは、シンブルで使われるキーと関連付けされる値とを「=>」で接続して定義することで、キーを用いて参照することが可能です。そのためキーに機能にあたる文字列を指定すれば、配列のように連続したデータが何かが理解しやすいプログラムを記述できます。
ハッシュの例
hash = { :key => "value" } p hash[:key] # "value"が表示される
シンボルをハッシュの関係は、下記の記事でも詳しく紹介しているので参照してみてください。
アクセサの引数で渡すインスタンス変数名
アクセサとはクラスの外からアクセスできないインスタンス変数をアクセス可能にするためのメソッドです。そしてアクセサではインスタンス変数名をシンボルで指定します。
アクセサの使用例
class Sample1 attr_accessor :name def initialize name @name = name end end obj = Sample1.new "sample_obj" p obj.name
上の例は、インスタンス変数「@name」を、「attr_accessor :name」で外から参照可能にし、「p obj.name」で表示しています。インスタンス変数は「@name」ですが、アクセスでは「;name」、外から参照する場合は「name」を使う点に注意してください。
なお、インスタンス変数とattr_accessorの使い方については、下記の記事でも詳しく紹介しています。
【Rubyの基礎】インスタンス変数の基本とattr_accessorの使い方
sendメソッド引数で渡すメソッド名
sendメソッドおよび__send__メソッドは、privateでクラス内でのみ使用するメソッドを、外から動作させるためなどで利用するメソッドです。sendメソッドおよび__send__メソッドでは、シンボルで指定したメソッドを呼び出し、指定したメソッドの結果を返します。
sendメソッドの例
class Sample1 private def s1_private puts "Call private method." end end s1 = Sample1.new s1.send :s1_private # s1.s1_privateはプライベートメソッドのため実行できない
enumで指定するカラム名
enumとは、1つのカラムにハッシュを使って複数個の定数を保存できるもので、カラムの定義にシンボルを使用します。
数値に役割を割り当てた場合、プログラム上では数字そのものではなく、それに関連付けしたシンボルを利用した方が読み易く、同時にミスを減らせます。しかし、その割り当てをプログラムの中で勝手に変更できるようでは、不具合が発生します。
そこでenumではシンボルのカラム名を定義することで、その割り当てをプログラムの中で書き換えできないようにした仕組みです。
enumの利用例
enum rate: { good: 0, normal: 1, bad: 2 }
シンボルを使った例
次にシンボルを利用したRubyのプログラムの例として、先ほど紹介したハッシュとアクセサ、sendメソッドの3つのシンボルを使った例を紹介します。
class SymbolUseSample attr_accessor :hash # アクセサとしてシンボル:hashを使用 def initialize id, name, attr @hash = {:id => id, :name => name, :attr => attr } # ハッシュとしてシンボル:idなどを使用 end def view_hash print_hash end private def print_hash strs = "id:" + hash[:id] + ", name:" + hash[:name] + ", attr:" + hash[:attr] puts strs end end obj = SymbolUseSample.new "10", "Sample", "checked" obj.view_hash obj.send :print_hash # sendメソッドの引数としてシンボル:print_hashを使用
まとめ
Rubyのシンボルとは、今回紹介したようにハッシュの添え字などで使われる、文字列と1対1に対応するラベルのような機能です。ハッシュの他にアクセサで指定するインスタンス変数の代わりや、sendメソッドで指定するメソッドの代わり、enumで指定するカラム名で使えます。
いずれもRubyやRuby on Railsでプログラムを組む際に使える便利な機能です。ぜひ、使いこなせるようになりましょう。