type=class
superclass=Object
included=Comparable
extended=
dynamically_included=
dynamically_extended=
library=_builtin
aliases=
aliasof=

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

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

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

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

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

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

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

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

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

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


  * ハッシュのキー { :key => "value" }
  * アクセサの引数で渡すインスタンス変数名 attr_reader :name
  * メソッド引数で渡すメソッド名 __send__ :to_s
  * C の enum 的な使用 (値そのものは無視してよい場合)

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

  * 新しく文字列を生成しない分やや効率がよく、比較も高速。
  * 文字の意味がはっきりするのでコードが読みやすくなる
  * immutable なので内容を書き換えられる心配がない

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

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

==== GC

内部的にシンボルは

  * シンボルの情報を記録するテーブル
  * そのテーブルの要素を指し示すポインタ

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

一方、テーブルに記録された情報はプログラムが動いている間
はずっと保持しつづけられます。そのため、以下のようなコード

  rng = Random.new
  100000.times do { rng.bytes(1000).intern }

はテーブルのサイズを増大させ、メモリを圧迫します。

例えば web アプリケーションのようなプロセスを動かしつづけるような
アプリケーションにおいて、ユーザからの入力を [[m:String#intern]] で
シンボルに変換するような実装をすると、DoSに弱くなる可能性があります。
