type=class
superclass=Object
included=Comparable
extended=
dynamically_included=JSON=Generator=GeneratorMethods=String
dynamically_extended=JSON=Generator=GeneratorMethods=String=Extend
library=_builtin
aliases=
aliasof=

文字列のクラスです。
NUL 文字を含む任意のバイト列を扱うことができます。
文字列の長さにはメモリ容量以外の制限はありません。

文字列は通常、文字列リテラルを使って生成します。
以下に文字列リテラルの例をいくつか示します。

  'str\\ing'   # シングルクオート文字列 (エスケープシーケンスがほぼ無効)
  "string\n"   # ダブルクオート文字列 (エスケープシーケンスがすべて有効)
  %q(str\\ing) # 「%q」文字列 (エスケープシーケンスがほぼ無効、デリミタが変えられる)
  %Q(string\n) # 「%Q」文字列 (エスケープシーケンスがすべて有効、デリミタが変えられる)

  # ヒアドキュメント
  <<End
  この行はヒアドキュメント
  End

  # ダブルクオートヒアドキュメント (クオートなしの場合と同じ)
  <<"End"
  この行はヒアドキュメント
  End

  # シングルクオートヒアドキュメント (一切のエスケープシーケンスが無効)
  <<'End'
  この行はヒアドキュメント
  End

  # 終端記号がインデントされたヒアドキュメント
  # シングルクオート、ダブルクオートとの併用も可能
  <<-End
  この行はヒアドキュメント (終端記号をインデントできる)
     End

===[a:mutable] 破壊的な変更

Ruby の String クラスは mutable です。
つまり、オブジェクト自体を破壊的に変更できます。

「破壊的な変更」とは、あるオブジェクトの内容自体を変化させることです。
例えば文字列のすべての文字を破壊的に大文字へ変更する
[[m:String#upcase!]] メソッドの使用例を以下に示します。

  a = "string"
  b = a
  a.upcase!
  p a   # => "STRING"
  p b   # => "STRING"

この例では、a に対してメソッドを呼んだにも関わらず b も変更されています。
これは、変数 a と b が一つの文字列オブジェクトを指していて、
upcase! メソッドでそのオブジェクト自体が変更されたからです。

upcase! の非破壊版である [[m:String#upcase]] を使った例を以下に示します。
こちらでは a の変更が b に波及しません。

  a = "string"
  b = a
  a = a.upcase
  p a   # => "STRING"
  p b   # => "string"

一般には、破壊的「ではない」メソッドを
中心に使っていくほうがバグが出にくくなります。

String クラスのメソッドには破壊的なメソッドも非破壊的なメソッドもあります。
破壊的なメソッドの例としては concat, sub!, upcase! などが挙げられます。
非破壊的なメソッドの例としては index, sub, upcase などが挙げられます。

同じ動作で破壊的なメソッドと非破壊的なメソッドの両方が定義されているときは、
破壊的なバージョンには名前の最後に「!」が付いています。
例えば upcase メソッドは非破壊的で、upcase! メソッドは破壊的です。

ただし、この命名ルールを
「破壊的なメソッドにはすべて『!』が付いている」と解釈しないでください。
例えば concat には「!」が付いていませんが、破壊的です。あくまでも、
「『!』が付いているメソッドと付いていないメソッドの両方があるときは、
『!』が付いているほうが破壊的」というだけです。
「『!』が付いているならば破壊的」は常に成立しますが、逆は必ずしも成立しません。

===[a:m17n] 多言語化と文字列のエンコーディング

String オブジェクトは自身のエンコーディング情報を持ちます。
インスタンスメソッドはエンコーディングに従い、1バイトではなく1文字を単位として動作します。
エンコーディングの変換にはメソッド [[m:String#encode]] を使います。

動作例:  (注)一行目にmagic commentが必要です。
  # vim:set fileencoding=UTF-8:
  p "いろは".size      #=> 3 
  p "漢字"[0]          #=> "漢"
  p "山本山".reverse   #=> "山本山" (回文なので分からないですね)
  p "ループ".reverse   #=> "プール"
 
  s = "ruビー"
  s[0..1] = "ル" 
  p s                  #=> "ルビー"
 
  e = "言語".encode("EUC-JP")
  u = "言語".encode("UTF-8")
  p e.encoding                   #=> Encoding::EUC_JP
  p u.encoding                   #=> Encoding::UTF_8

より詳しく知りたい場合は、[[d:spec/m17n]] を参照してください。

==== 文字列同士の比較・結合

文字列同士の比較・結合などでは両者のエンコーディングを意識する必要があります。
例えば [[m:String#==]] や [[m:String#eql?]] は両者のエンコーディングが等しく
バイト列表現が等しい場合にのみ true を返します。
このときエンコーディングが UTF-8 であっても正規化せずに比較します。
文字列の結合も同様です。異なるエンコーディング同士の文字列を結合する時は
明示的にエンコーディングを変換する必要があります。

動作例:  (注)一行目にmagic commentが必要です。
  # vim:set fileencoding=UTF-8:
  s = "いろは"
  a = s.encode("EUC-JP")
  b = s.encode("UTF-8")
  p a == b                            #=> false
 
  s = "合".encode("EUC-JP")
  p s + "\u{4f53}".encode("EUC-JP")   #=> "合体"
  p s + "\u{4f53}"                    #=> ArgumentError 

[[m:String#eql?]] はハッシュのキーの比較に使われますので、
ハッシュのキーに非 ASCII 文字列を使う場合には注意が必要です。

動作例:  (注)一行目にmagic commentが必要です。
  # encoding: UTF-8
  h = {}
  s = "いろは"
  s.force_encoding("EUC-JP")
  h[s] = 1
  s.force_encoding("ASCII-8BIT")
  p h[s]                             #=> nil

==== 7bit クリーンな文字列

ASCII 互換エンコーディングをもつ 7bit クリーンな文字列は
エンコーディングに関わらず ASCII として扱うことができます。
例えば [[m:String#==]] は両者の文字エンコーディングが異なっていても
true を返します。
ASCII 互換エンコーディングをもつ文字列にエンコーディングの変換なしで結合することができます。

例:

  s = "abc"
  a = s.encode("EUC-JP")
  b = s.encode("UTF-8")
  p a == b                           #=> true
  p a + b                            #=> "abcabc"

ここで言う「ASCII互換エンコーディング」とは、コードポイントが同一という意味ではなく
バイト列が同じことを意味します。従って UTF-16 はASCII互換ではありません。
また厳密性を追求せず、おおむね互換なら互換と呼びます。よって Shift_JIS は ASCII 互換です。

==== バイト列を表す文字列

文字列ではない単なるバイト列も String オブジェクトで表されます。
その時のエンコーディングは ASCII-8BIT です。
