class Symbol

要約

シンボルを表すクラス。シンボルは任意の文字列と一対一に対応するオブジェクトです。

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

シンボルオブジェクトは以下のようなリテラルで得られます。

:symbol
:'symbol'
%s!symbol! # %記法

生成されたシンボルの一覧は Symbol.all_symbols で得られます。一番目のリテラルでシンボルを表す場合、`:' の後には識別子、メソッド名(`!',`?',`=' などの接尾辞を含む)、変数名 (`$'などの接頭辞を含む)、再定義できる演算子のいずれかに適合するものしか書くことはできません(そうでなければ文法エラーになります)。そうでない文字列をシンボルにしたい場合は残りの表記か String#intern を使用してください。

シンボルの実装と用途

実装

Rubyの内部実装では、メソッド名や変数名、定数名、クラス名などの`名前'を整数で管理しています。これは名前を直接文字列として処理するよりも速度面で有利だからです。そしてその整数をRubyのコード上で表現したものがシンボルです。

シンボルは、ソース上では文字列のように見え、内部では整数として扱われる、両者を仲立ちするような存在です。

名前を管理するという役割上、シンボルと文字列は一対一に対応します。また、文字列と違い、immutable (変更不可)であり、同値ならば必ず同一です。

p "abc" == "abc" #=> true
p "abc".equal?("abc") #=> false
p :abc == :abc #=> true
p :abc.equal?(:abc) #=> true ←同値ならば同一

用途

実用面では、シンボルは文字の意味を明確にします。`名前'を指し示す時など、文字列そのものが必要なわけではない時に用います。

シンボルを使うメリットは

大抵のメソッドはシンボルの代わりに文字列を引数として渡すこともできるようになっています。

Symbol クラスのメソッドには、String クラスのメソッドと同名で似た働きをするものもあります。

GC

内部的にシンボルは

の2つにより実装されています。そのため同じシンボル(同じ文字列から作られたシンボル)を複製しても同じ要素へのポインタが使われるだけなのでメモリ使用量は普通の文字列と比べて少ないです。

2.2.0 以降においては、テーブルに記録された情報は Ruby によって GC されます。すなわち、ある使わなくなったシンボルのテーブル上の情報はGCによって削除されます。

2.1 以前ではこの機能がなかったため、ユーザからの入力をシンボルに変換するようなプログラムは DoS に対して弱い可能性がありましたが、そのような問題は2.2以降では解決されました。

ただし拡張ライブラリ内で rb_intern によって生成されたシンボルに関するテーブル上の情報はGCされませんので注意してください。

目次

特異メソッド
インスタンスメソッド

継承しているメソッド

Comparableから継承しているメソッド

特異メソッド

all_symbols -> [Symbol][permalink][rdoc]

定義済みの全てのシンボルオブジェクトの配列を返します。

p Symbol.all_symbols #=> [:RUBY_PLATFORM, :RUBY_VERSION, ...]

リテラルで表記したシンボルのうち、コンパイル時に値が決まるものはその時に生成されます。それ以外の式展開を含むリテラルや、メソッドで表記されたものは式の評価時に生成されます。 (何にも使われないシンボルは最適化により生成されないことがあります)

def number
  'make_3'
end

p Symbol.all_symbols.select{|sym|sym.to_s.include? 'make'}
#=> [:make_1, :make_2]

re  = #確実に生成されるように代入操作を行う
:make_1,
:'make_2',
:"#{number}",
'make_4'.intern

p Symbol.all_symbols.select{|sym|sym.to_s.include? 'make'}
#=> [:make_1, :make_2, :make_3, :make_4]

インスタンスメソッド

self <=> other -> -1 | 0 | 1[permalink][rdoc]

self と other のシンボルに対応する文字列を ASCII コード順で比較して、 self が大きい時には正の整数、等しい時には 0、小さい時には負の整数を返します。

[PARAM] other:
比較対象のシンボルを指定します。
p :aaa <=> :xxx  # => -1
p :aaa <=> :aaa  # => 0
p :xxx <=> :aaa  # => 1

[SEE_ALSO] String#<=>

self == other -> true | false[permalink][rdoc]

other が同じシンボルの時に真を返します。そうでない場合は偽を返します。

[PARAM] other:
比較対象のシンボルを指定します。

例:

:aaa == :aaa    #=> true
:aaa == :xxx    #=> false
self =~ other -> Integer | nil[permalink][rdoc]

正規表現 other とのマッチを行います。

(self.to_s =~ other と同じです。)

[PARAM] other:
比較対象のシンボルを指定します。
[RETURN]
マッチが成功すればマッチした位置のインデックスを、そうでなければ nil を返します。
p :foo =~ /foo/    # => 0
p :foobar =~ /bar/ # => 3
p :foo =~ /bar/    # => nil

[SEE_ALSO] String#=~

self[nth] -> String | nil[permalink][rdoc]
slice(nth) -> String | nil

nth 番目の文字を返します。

(self.to_s[nth] と同じです。)

[PARAM] nth:
文字の位置を表す整数を指定します。
:foo[0] # => "f"
:foo[1] # => "o"
:foo[2] # => "o"
self[nth, len] -> String | nil[permalink][rdoc]
slice(nth, len) -> String | nil

nth 番目から長さ len の部分文字列を新しく作って返します。

(self.to_s[nth, len] と同じです。)

[PARAM] nth:
文字の位置を表す整数を指定します。
[PARAM] len:
文字列の長さを指定します。
:foo[1, 2] # => "oo"
self[substr] -> String | nil[permalink][rdoc]
slice(substr) -> String | nil

self が substr を含む場合、一致した文字列を新しく作って返します。

(self.to_s[substr] と同じです。)

例:

:foobar.slice("foo")   # => "foo"
:foobar.slice("baz")   # => nil
self[regexp, nth = 0] -> String | nil[permalink][rdoc]
slice(regexp, nth = 0) -> String | nil

正規表現 regexp の nth 番目の括弧にマッチする最初の部分文字列を返します。

(self.to_s[regexp, nth] と同じです。)

[PARAM] regexp:
正規表現を指定します。
[PARAM] nth:
取得したい正規表現レジスタのインデックスを指定します。
:foobar[/bar/] # => "bar"
:foobarbaz[/(ba.)(ba.)/, 0] # => "barbaz"
:foobarbaz[/(ba.)(ba.)/, 1] # => "bar"
:foobarbaz[/(ba.)(ba.)/, 2] # => "baz"
self[range] -> String | nil[permalink][rdoc]
slice(range) -> String | nil

rangeで指定したインデックスの範囲に含まれる部分文字列を返します。

(self.to_s[range] と同じです。)

[PARAM] range:
取得したい文字列の範囲を示す Range オブジェクトを指定します。
:foo[0..1] # => "fo"

[SEE_ALSO] String#[], String#slice

capitalize(*options) -> Symbol[permalink][rdoc]

シンボルに対応する文字列の先頭の文字を大文字に、残りを小文字に変更したシンボルを返します。

(self.to_s.capitalize.intern と同じです。)

:foobar.capitalize     #=> :Foobar
:fooBar.capitalize     #=> :Foobar
:FOOBAR.capitalize     #=> :Foobar
:"foobar--".capitalize # => "Foobar--"

[SEE_ALSO] String#capitalize

casecmp(other) -> -1 | 0 | 1[permalink][rdoc]

Symbol#<=> と同様にシンボルに対応する文字列の順序を比較しますが、アルファベットの大文字小文字の違いを無視します。

Symbol#casecmp? と違って大文字小文字の違いを無視するのは Unicode 全体ではなく、A-Z/a-z だけです。

[PARAM] other:
比較対象のシンボルを指定します。
:aBcDeF.casecmp(:abcde)     #=> 1
:aBcDeF.casecmp(:abcdef)    #=> 0
:aBcDeF.casecmp(:abcdefg)   #=> -1
:abcdef.casecmp(:ABCDEF)    #=> 0
:"\u{e4 f6 fc}".casecmp(:"\u{c4 d6 dc}") #=> 1

nil は文字列のエンコーディングが非互換の時に返されます。

"\u{e4 f6 fc}".encode("ISO-8859-1").to_sym.casecmp(:"\u{c4 d6 dc}")   #=> nil

[SEE_ALSO] String#casecmp

casecmp?(other) -> bool | nil[permalink][rdoc]

大文字小文字の違いを無視しシンボルを比較します。シンボルが一致する場合には true を返し、一致しない場合には false を返します。

[PARAM] other:
比較対象のシンボルを指定します。
:abcdef.casecmp?(:abcde)     #=> false
:aBcDeF.casecmp?(:abcdef)    #=> true
:abcdef.casecmp?(:abcdefg)   #=> false
:abcdef.casecmp?(:ABCDEF)    #=> true
:"\u{e4 f6 fc}".casecmp?(:"\u{c4 d6 dc}") #=> true

nil は文字列のエンコーディングが非互換の時に返されます。

"\u{e4 f6 fc}".encode("ISO-8859-1").to_sym.casecmp?(:"\u{c4 d6 dc}")   #=> nil

[SEE_ALSO] String#casecmp?

downcase(*options) -> Symbol[permalink][rdoc]

大文字を小文字に変換したシンボルを返します。

(self.to_s.downcase.intern と同じです。)

:FOO.downcase #=> :foo

[SEE_ALSO] String#downcase

empty? -> bool[permalink][rdoc]

自身が :"" (length が 0 のシンボル)かどうかを返します。

:"".empty?  #=> true
:foo.empty? #=> false

[SEE_ALSO] String#empty?

encoding -> Encoding[permalink][rdoc]

シンボルに対応する文字列のエンコーディング情報を表現した Encoding オブジェクトを返します。

例:

# encoding: utf-8

:foo.encoding        # => #<Encoding:US-ASCII>
:あかさたな.encoding   # => #<Encoding:UTF-8>

[SEE_ALSO] String#encoding

id2name -> String[permalink][rdoc]
to_s -> String

シンボルに対応する文字列を返します。

逆に、文字列に対応するシンボルを得るには String#intern を使います。

p :foo.id2name  # => "foo"
p :foo.id2name.intern == :foo  # => true

[SEE_ALSO] String#intern

inspect -> String[permalink][rdoc]

自身を人間に読みやすい文字列にして返します。

:fred.inspect   #=> ":fred"
intern -> self[permalink][rdoc]
to_sym -> self

self を返します。

例:

:foo.intern   # => :foo

[SEE_ALSO] String#intern

length -> Integer[permalink][rdoc]
size -> Integer

シンボルに対応する文字列の長さを返します。

(self.to_s.length と同じです。)

:foo.length #=> 3

[SEE_ALSO] String#length, String#size

match(other) -> MatchData | nil[permalink][rdoc]

正規表現 other とのマッチを行います。

(self.to_s.match(other) と同じです。)

[PARAM] other:
比較対象のシンボルを指定します。
[RETURN]
マッチが成功すれば MatchData オブジェクトを、そうでなければ nil を返します。
p :foo.match(/foo/)    # => #<MatchData "foo">
p :foobar.match(/bar/) # => #<MatchData "bar">
p :foo.match(/bar/)    # => nil

[SEE_ALSO] String#match

[SEE_ALSO] Symbol#match?

match?(regexp, pos = 0) -> bool[permalink][rdoc]

regexp.match?(self, pos) と同じです。 regexp が文字列の場合は、正規表現にコンパイルします。詳しくは Regexp#match? を参照してください。

例:

:Ruby.match?(/R.../)    # => true
:Ruby.match?('Ruby')    # => true
:Ruby.match?('Ruby',1)  # => false
:Ruby.match?('uby',1)   # => true
:Ruby.match?(/P.../)    # => false
$&                      # => nil

[SEE_ALSO] Regexp#match?, String#match?

succ -> Symbol[permalink][rdoc]
next -> Symbol

シンボルに対応する文字列の「次の」文字列に対応するシンボルを返します。

(self.to_s.next.intern と同じです。)

:a.next   # => :b
:foo.next # => :fop

[SEE_ALSO] String#succ

swapcase(*options) -> Symbol[permalink][rdoc]

'A' から 'Z' までのアルファベット大文字を小文字に、'a' から 'z' までのアルファベット小文字を大文字に変更したシンボルを返します。

(self.to_s.swapcase.intern と同じです。)

p :ABCxyz.swapcase   # => :abcXYZ
p :Access.swapcase   # => :aCCESS

[SEE_ALSO] String#swapcase

to_proc -> Proc[permalink][rdoc]

self に対応する Proc オブジェクトを返します。

生成される Proc オブジェクトを呼びだす(Proc#call)と、 Proc#callの第一引数をレシーバとして、 self という名前のメソッドを残りの引数を渡して呼びだします。

明示的に呼ぶ例

:to_i.to_proc["ff", 16]  # => 255 ← "ff".to_i(16)と同じ
暗黙に呼ばれる例

# メソッドに & とともにシンボルを渡すと
# to_proc が呼ばれて Proc 化され、
# それがブロックとして渡される。
(1..3).collect(&:to_s)  # => ["1", "2", "3"]
(1..3).select(&:odd?)   # => [1, 3]

[SEE_ALSO] メソッド呼び出し(super・ブロック付き・yield)/ブロック付きメソッド呼び出し

upcase(*options) -> Symbol[permalink][rdoc]

小文字を大文字に変換したシンボルを返します。

(self.to_s.upcase.intern と同じです。)

:foo.upcase #=> :FOO

[SEE_ALSO] String#upcase