3. 文字列

文字リテラル

先ほどから紹介してきた通り、文字列はダブルクオーテーション "" で囲んで表現します。
シングルクオーテーション''でも表せますが、挙動に違いがあるため注意が必要です。

ダブルクオーテーション

quotations.rb
1
2
3
4
5
6
7
name = "太郎"

puts "こんにちは#{name}"
#=> こんにちは太郎

print "太郎\n"
#=> 太郎(改行される)

シングルクオーテーション

上記の quotations.rbputsメソッドで利用しているダブルクオーテーション""を、シングルクオーテーション''に書き換えてみましょう。

quotations.rb
1
2
3
4
5
6
7
name = "太郎"

puts 'こんにちは#{name}'
#=> こんにちは#{name}

print '太郎\n'
#=> 太郎\n(改行されずに表示される)

''で囲った文字は、そのまま表示されます。
混乱を避けるために、研修中は基本的に""を使用しましょう。

文字列連結

演算子による連結

文字列同士なら+でつなげることができます。

plus.rb
1
2
3
4
5
hello = "Hello!"
name = "太郎"

puts hello + name
#=> Hello!太郎

しかし、一般的にRubyで上記のように表示する場合は、以下に示す式展開を使うことが多いです

式展開

式展開を用いると、文字列中に直接変数の値を文字列として入れ込むことができます。

variable_expansion.rb
1
2
3
4
5
hello = "Hello!"
name = "太郎"

puts "#{hello}#{name}"
#=> Hello!太郎

連結時の注意

""で囲ったものは、例え数字であっても"文字"として扱われるため、「文字+数値」だとエラーが起こります。

string_numbers.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
p 100
#=> 100 (Numeric クラス)

p "100"
#=> "100" (String クラス)

p 100 + 1
#=> 101

p "100" + "1"
#=> "1001"

p "100" + 1
#=> TypeError: no implicit conversion of Fixnum into String

Note : クラスを知りたかったら .class

変数や数字に.classをつけると、何クラスかが分かります。

class_method.rb
1
2
3
4
5
p 100.class
#=> Integer (Numericの一種)

p "100".class
#=> String

参考:rubyクラス一覧

Stringクラスのメソッド

数値への変換(to_i)

(文字の結合ではなく計算がしたいときなど)

to_i.rb
1
2
3
4
5
6
7
num = "100"

p num.to_i + 1
#=> 101

p num + 1
#=> Error

文字列の置換(sub・gsub)

sub.rb
1
2
3
4
5
6
7
str = "Pen Pineapple Apple Pen"

p str.sub("Pen", "Orange")
#=> "Orange Pineapple Apple Pen"

p str.gsub("Pen", "Orange")
#=> "Orange Pineapple Apple Orange"

subgsubメソッドは、第1引数で指定した文字列を第2引数で指定した文字列に置き換えます。
subは文字列中で最初に見つかったもののみ、gsubメソッドは文字列中で見つかったすべてを置き換えます。
第1引数には正規表現を与えることも可能です。
正規表現については講義中の説明は割愛しますが、正規表現のページで説明していますので、興味があったら見てみてください。

文字列の分割(split)

下記の例だと、文字列を,(カンマ)で区切った配列に変換します。
配列については後述します。

split.rb
1
2
p "001,Suginami Taro,Yokohama".split(",")
#=> ["001", "Suginami Taro", "Yokohama"]

シンボル

シンボルはコロン:を先頭につけて表現します。

symbol.rb
1
2
3
4
5
6
7
sym = :symbol    #シンボル
puts sym
#=> symbol

sym = :'symbol'  #文字列で表現してシンボルにすることも可能
puts sym
#=> symbol

文字列の項目内にありますが、正確には文字列ではありません。

文字列の代わりに用いることもできますが、必ずしも文字列と同じ振る舞いをするわけではありません。
例えば、ハイフン-はコロン:のみのシンボルには利用できません。

1
2
sym = :hy-phen # コロンのみだとエラー
#=> NameError (undefined local variable or method `phen' for main:Object)
1
2
3
sym = :'hy-phen' # 文字列で表現してからならできる
puts sym
#=> hy-phen

また、数値への変換to_iで紹介した.to_iメソッドも利用できません。
これは、文字列に対して利用できるメソッドだからです。

1
2
3
4
sym = :'100'
p sym.to_i + 1
#=> NoMethodError (undefined method `to_i' for :"100":Symbol)
# Did you mean?  to_s

具体的な用途については後述します。

Note : シンボルの正体

シンボルの正体は、文字列ではなく整数で、「オブジェクトに割り当てられている一意のid」に一対一で対応しています。
chepter2のnoteで出てきた.object_idメソッドを利用して確認してみましょう。

1
2
3
4
5
6
7
8
9
10
11
12
13
sym1 = :symbol
sym2 = :symbol

# どちらも同じ値 p sym1.object_id #=> 824668 p sym2.object_id #=> 824668
str1 = "string" str2 = "string"
# 違う値 p str1.object_id # => 70333273170320 p str2.object_id # => 70333273170300

上記からシンボルは、コード上でも内部でも、同じ値を持つことがわかります。
対して文字列は、コード上の値が同じでも、内部では違う値を持つことがわかります。


つまり、同じメモリ領域を利用するか、毎回違うメモリ領域を利用するかの違いです。


この原理を利用して、メモリの消費を抑えるために、メソッド名などにも使されます。
また、実態は整数なので、計算速度が求められる処理に利用されます。


演習問題

問1

以下の変数を使って、下記の文章を出力してください。

1
2
3
4
first_name = "太郎"
last_name  = "杉並"
old = 59
#=> 私の名前は杉並太郎です。59歳です。

問2

以下のstr変数を /(スラッシュ)で分けて、配列として出力してください。

1
2
str = "apple/orange/grape"
#=> ["apple", "orange", "grape"]

問3

以下のstr変数の文中のTokyoをすべてKoenjiに置換してください。

1
2
str = "I love Tokyo! I don't wanna leave Tokyo!"
#=> I love Koenji! I don't wanna leave Koenji!