Ruby 2.1.0 リファレンスマニュアル > ライブラリ一覧 > 組み込みライブラリ > Symbolクラス
クラスの継承リスト: Symbol < Comparable < Object < Kernel < BasicObject
シンボルを表すクラス。シンボルは任意の文字列と一対一に対応するオブジェクトです。
文字列の代わりに用いることもできますが、必ずしも文字列と同じ振る舞いをするわけではありません。 同じ内容のシンボルはかならず同一のオブジェクトです。
シンボルオブジェクトは以下のようなリテラルで得られます。
: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 クラスのメソッドと同名で似た働きをするものもあります。
内部的にシンボルは
の2つにより実装されています。そのため 同じシンボル(同じ文字列から作られたシンボル)を 複製しても同じ要素へのポインタが使われるだけなので メモリ使用量は普通の文字列と比べて少ないです。
一方、テーブルに記録された情報はプログラムが動いている間 はずっと保持しつづけられます。そのため、以下のようなコード
rng = Random.new 100000.times do { rng.bytes(1000).intern }
はテーブルのサイズを増大させ、メモリを圧迫します。
例えば web アプリケーションのようなプロセスを動かしつづけるような アプリケーションにおいて、ユーザからの入力を String#intern で シンボルに変換するような実装をすると、DoSに弱くなる可能性があります。
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、小さい時には負の整数を返し ます。
p :aaa <=> :xxx # => -1 p :aaa <=> :aaa # => 0 p :xxx <=> :aaa # => 1
[SEE_ALSO] String#<=>
self == other -> true | false
[permalink][rdoc]other が同じシンボルの時に真を返します。 そうでない場合は偽を返します。
self =~ other -> Integer | nil
[permalink][rdoc]match(other) -> Integer | nil
正規表現 other とのマッチを行います。
(self.to_s =~ other と同じです。)
p :foo =~ /foo/ # => 0 p :foobar =~ /bar/ # => 3 p :foo =~ /bar/ # => nil
[SEE_ALSO] String#=~, String#match
self[nth] -> String | nil
[permalink][rdoc]slice(nth) -> String | nil
nth 番目の文字を返します。
(self.to_s[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] と同じです。)
:foo[1, 2] # => "oo"
self[substr] -> String | nil
[permalink][rdoc]slice(substr) -> String | nil
self が substr を含む場合、一致した文字列を新しく作って返します。
(self.to_s[substr] と同じです。)
self[regexp, nth = 0] -> String | nil
[permalink][rdoc]slice(regexp, nth = 0) -> String | nil
正規表現 regexp の nth 番目の括弧にマッチする最初の部分文字列を返します。
(self.to_s[regexp, 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] と同じです。)
:foo[0..1] # => "fo"
[SEE_ALSO] String#[], String#slice
capitalize -> 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#<=> と同様にシンボルに対応する文字列の順序を比較しますが、 アルファベットの大文字小文字の違いを無視します。
: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
downcase -> 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 オブ ジェクトを返します。
[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 を返します。
[SEE_ALSO] String#intern
length -> Integer
[permalink][rdoc]size -> Integer
シンボルに対応する文字列の長さを返します。
(self.to_s.length と同じです。)
:foo.length #=> 3
[SEE_ALSO] String#length, String#size
succ -> Symbol
[permalink][rdoc]next -> Symbol
シンボルに対応する文字列の「次の」文字列に対応するシンボルを返します。
(self.to_s.next.intern と同じです。)
:a.next # => :b :foo.next # => :fop
[SEE_ALSO] String#succ
swapcase -> 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)と同じです (1..3).collect(&:to_s) #=> ["1", "2", "3"] (1..3).inject(&:+) #=> 6
upcase -> Symbol
[permalink][rdoc]小文字を大文字に変換したシンボルを返します。
(self.to_s.upcase.intern と同じです。)
:foo.upcase #=> :FOO
[SEE_ALSO] String#upcase