Ruby は、短く読みやすいコードを書けるように作られたプログラミング言語です。Web アプリケーションのフレームワークの Ruby on Rails で広く使われているほか、ちょっとした作業の自動化にも向いています。ここでは、Ruby を始めたばかりの人に向けて、範囲、くり返し、ブロックといった基本を、小さな例で紹介します。

irb で試し、ruby で実行する

Ruby を入れると、irb (Interactive Ruby) というコマンドが使えるようになります。irb では、式を 1 行打つたびに、その結果がすぐに表示されます。

ruby -v    # 入っている Ruby の版を確かめる
irb        # 対話的に試せる環境を起動する
irb(main):001> 1 + 2
=> 3
irb(main):002> "Ruby".upcase
=> "RUBY"
irb(main):003> exit

=> のあとに表示されるのが、その式の値です。プロンプトの表示は版によって少し違います。終えるときは exit と打ちます。

まとまったコードは、拡張子が .rb のファイルに書いて、ruby コマンドで実行します。

# hello.rb
name = "Ruby"
puts "こんにちは、#{name}"
ruby hello.rb
# こんにちは、Ruby

Ruby 2.0 からは、ソースコードは標準で UTF-8 として読まれます。日本語を含むファイルも、UTF-8 で保存すればそのまま動きます。

範囲オブジェクト

1..5 のように書くと、1 から 5 までの範囲を表すオブジェクト (Range) になります。.. は終わりの値を含み、... は含みません。

(1..5).to_a          # => [1, 2, 3, 4, 5]
(1...5).to_a         # => [1, 2, 3, 4]
(1..10).step(2).to_a # => [1, 3, 5, 7, 9]
("a".."e").to_a      # => ["a", "b", "c", "d", "e"]

このように、文字列の範囲も作れます。文字列の範囲は、「次の値」を返す succ メソッドで、始まりから順に値を作っていきます。ひらがなで試すと、思ったものと違う結果になることがあります。

("あ".."お").to_a
# => ["あ", "ぃ", "い", "ぅ", "う", "ぇ", "え", "ぉ", "お"]
("あ".."ん").to_a.size # => 82

Unicode では、ひらがなは小さい文字 (ぁ、ぃ…) や濁音 (が、ぎ…) も含めて、文字コードの順に並んでいます。そのため、"あ".."ん" には、五十音の 46 文字だけでなく、小さい文字、濁音・半濁音、「ゐ」「ゑ」も入ります。五十音だけがほしいときは、範囲から作るより、必要な文字を並べた文字列から作るほうが確実です。

"あいうえおかきくけこ".chars
# => ["あ", "い", "う", "え", "お", "か", "き", "く", "け", "こ"]

each・map・select・each_with_index

配列や範囲の要素を順に扱うメソッドは、Ruby でもっともよく使うものです。

fruits = ["りんご", "みかん", "ぶどう"]

# each: 要素を 1 つずつ取り出して処理する
fruits.each { |fruit| puts fruit }

# each_with_index: 要素と、0 から始まる番号を受け取る
fruits.each_with_index do |fruit, i|
  puts "#{i + 1}. #{fruit}"
end
# 1. りんご
# 2. みかん
# 3. ぶどう

# map: 各要素を変換した、新しい配列を返す
(1..5).map { |n| n * n }       # => [1, 4, 9, 16, 25]

# select: 条件に合う要素だけを集めた、新しい配列を返す
(1..10).select { |n| n.even? } # => [2, 4, 6, 8, 10]
  • each は、処理を終えたあと、元の配列 (呼び出したオブジェクト) をそのまま返します。処理の結果を集めたいときは map を使います
  • map や select は、元の配列を変えずに、新しい配列を返します
  • select { |n| n.even? } は、select(&:even?) と短く書くこともできます

文字列の連結と式展開

name = "Ruby"
"こんにちは、" + name + "さん" # => "こんにちは、Rubyさん"
"こんにちは、#{name}さん"       # => "こんにちは、Rubyさん"
'こんにちは、#{name}さん'       # => "こんにちは、\#{name}さん" (展開されない)

count = 3
"合計: " + count       # TypeError (数値は自動では文字列にならない)
"合計: " + count.to_s  # => "合計: 3"
"合計: #{count * 2}"   # => "合計: 6"
  • + で文字列をつなげます。数値などをつなげるときは、to_s で文字列にします
  • ダブルクォートの文字列の中では、#{...} で式の値を埋め込めます (式展開)。中には変数だけでなく、計算などの式も書けます
  • シングルクォートの文字列の中では式展開は行われず、書いたとおりの文字になります
  • << は、元の文字列の後ろに書き足します。+ と違い、元の文字列そのものが変わります

ブロック

{ ... } や do ... end で囲んだ部分はブロックと呼ばれ、メソッドに渡す処理のまとまりです。|fruit| のように縦線で囲んだ名前で、メソッドから値を受け取ります。1 行で済むときは { }、複数行になるときは do ... end を使うのが一般的です。

自分で作るメソッドでも、yield でブロックを呼び出せます。ブロックの中で最後に評価した式の値が、yield の値になります。

def twice
  yield
  yield
end

twice { puts "こんにちは" }
# こんにちは
# こんにちは

def with_tag(tag)
  "<#{tag}>#{yield}</#{tag}>"
end

with_tag("strong") { "大事なこと" } # => "<strong>大事なこと</strong>"

each や map も、このようにブロックを受け取って、要素ごとに呼び出すメソッドです。ブロックの仕組みがわかると、Ruby のコードがぐっと読みやすくなります。

まとめ

  • irb で式を試し、まとまったコードは .rb のファイルにして ruby コマンドで実行する
  • 1..5 は終わりを含む範囲、1...5 は含まない範囲。文字列の範囲は文字コードの順に作られるので、ひらがなでは小さい文字や濁音も含まれる
  • each は順に処理、map は変換、select は絞り込み、each_with_index は番号付きの処理
  • 式展開の #{...} は、ダブルクォートの文字列の中だけで働く
  • ブロックはメソッドに渡す処理のまとまりで、yield で呼び出せる

参考