Edited at

[Ruby入門] 05. 制御構文(条件分岐、繰り返し処理)

More than 1 year has passed since last update.

>> 連載の目次は こちら!

※コメント欄にて、@raccy さんからご指摘頂いた件を補足しておきます。

この記事では、「for文」「if文」「while文」といった表現をしていますが、Rubyでは、それらは「文」ではなく「式」です。

式であるからには、最終的に何かしらの値を返すため、たとえば変数への代入なども可能になります。

(例文は、コメント欄を参照してください)


1. 条件分岐


rubyにおける真偽

rubyでは、「false」と「nil」だけが偽となり、それ以外は全て「真」となる


if文

num = rand(1..10); p num

if num.between?(1, 3) then
puts '1 - 3'
elsif num.between?(4, 6) then
puts '4-6'
else
puts '7-10'
end


  • then は省略可能


unless文

anm = %w[ねこ いぬ ぱんだ].sample; puts anm

unless anm == "ぱんだ" then
puts "近所にいっぱいいるよ!"
else
puts "あんまりいないよ..."
end


  • 場面によっては「if !hoge 〜」より文章的でわかりやすいかな。上記の例は微妙だけど。

  • then は省略可能


超簡単なifを書きたい(if 修飾子)

debug = true

puts("バグってます!") if debug

・条件式も実行文も単純ならこの書き方は便利

・こちらにも unless がある


case文

fruits = ["Apple", "Orange", "Lemon", "Grape"].sample; puts fruits

case fruits
when "Apple" then
puts "甘いけどちょっと食べづらい"
when "Orange","Lemon" then
puts "柑橘系、酸っぱいよねー"
else
puts "ぶどう大好き!"
end


  • switch とか書かないのね

  • then は省略可能

  • 値を複数パターン拾えるのが特徴(上記のOrangeとLemonのとこ)

  • 判定には === 演算子が使われ、このとき判定の主体(レシーバー)はwhenの直後のオブジェクトになる。これが文字列や数値なら == と同じ


条件演算子

いわゆる三項演算子

vegeta = ["キャベツ", "きゅうり", "トマト"].sample; puts vegeta

result = (vegeta == 'きゅうり') ? 'きらい' : 'すき';
puts result


2. 繰り返し処理


最初に範囲オブジェクトの話

ruby でよく見る 1..9 みたいな表現。見たままで分かりやすいな

r1 = 1..5                   # 終端の値を含む

r2 = 1...5 # 終端の値を含まない
r3 = Range.new(1, 5) # 終端の値を含む
r4 = Range.new(1, 5, true) # 終端の値を含まない
arr = r1.to_a # 範囲から配列を作成 [1, 2, 3, 4, 5]


while文

month = 1

while month <= 12 do
puts month.to_s + '月: ' + ( (month <= 3) ? 'まだお年玉ある' : 'もう使っちゃった!' )
month = month + 1;
end


  • do は省略可能

  • 条件が偽の間繰り返す until 〜 do 〜 end もある(使うかな...)

  • whileにも、ifみたいに後方に置く簡易な記法があるが、こちらは使い道がないかも...


for文

# for文

for i in 1..3 do
puts i
end
puts i #ループ終了後も i が生きているので注意


  • for は、rubyではほとんど使われない...

  • forだと、インデックス変数がループ終了後も生きてるの注意

  • このような場合、普通は 後述のイテレータによるループを使う

  • do は省略可能


each | times | upto | downto メソッドを使ったイテレータによるループ

(1..3).each do |i|

puts i
end

3.times do |i|
puts i
end

1.upto(3) do |i|
puts i
end

3.downto(1) do |i|
puts i
end


  • times は 0から始まるインデックス的な値

  • upto | downto は見たままの数値が変数に入るので分かりやすいな

  • このループ方法なら、for文みたいにインデックス変数がループ終了後も生きてるなんてことはない

  • 順番に値を取り出すときは、オブジェクトの succ メソッドが呼ばれる。Integerオブジェクトなら順番が明確だから問題ない。

・しつこいけど do は省略可能

↑間違いです!

doブロックを渡すものなので、省略できません!


そのまんまな loop メソッド

i = 1

loop {
if (i > 5) then break end
puts i
i = i + 1
}


  • break 必須だね


ループを途中で抜けたり次に進んだりやり直したり...

break

next

redo

を使う。continueじゃないよ。