Ruby入門 - 制御構文

トップ > Ruby入門 > 制御構文

もし~ならば(if, then, else, elsif)

文法1
if expr [then]
  expression...
[elsif expr [then]
  expression...]...
[else
  expression...]
end
文法2
expression if expr

if は「もし」を意味します。式が真であれば、thenend までの処理を実行します。下記の例では、num の値が 10より大きければ BIG を表示します。then は省略可能です。

if num > 10 then
  puts "BIG"
end

else は「さもなくば」を意味します。下記の例では、num が 10より大きければ BIG を、さもなくば SMALL を表示します。

if num > 10 then
  puts "BIG"
else
  puts "SMALL"
end

elsif は「さもなくばもし」を意味します。下記の例では、num が 10より大きければ BIG を、10と等しければ NORMAL を、さもなくば SMALL を表示します。

if num > 10 then
  puts "BIG"
elsif num == 10 then
  puts "NORMAL"
else
  puts "SMALL"
end

下記の例も、num の値が 10 より大きければ BIG を表示します。

puts "BIG" if num > 10

PHP などでは数値の 0 や空文字列も偽とみなされますが、Ruby では false および nil のみが偽と判断され、0 や空文字を含むその他の値は真とみなされます。

if 0 then
  puts "OK"            #=> OK
end

もし~でなければ(unless, then)

文法1
unless expr [then]
  expression...
[else
  expression...]
end
文法2
expression unless expr

unless は「もし~でなければ」を意味します。下記の例では、num が 10 より小さくなければ、BIG を表示します。then は省略可能です。

unless num < 10 then
  puts "BIG"
end

下記の表記も可能です。

puts "BIG" unless num < 10

~のあいだ(while, do)

文法1
while expr [do]
  expression...
end
文法2
expression while expr

while は「~のあいだ」を意味します。下記の例では、i の値が 10よりも小さい間 i の値を表示します。do は省略可能です。

i = 0
while i < 10 do
  puts i
  i += 1
end

下記の例も同じように動作します。

i = 0
begin
  puts i
  i += 1
end while i < 10

~になるまでのあいだ(until, do)

文法1
until expr [do]
  expression...
end
文法2
expression until expr

until は「~になるまでのあいだ」を意味します。下記の例では、i の値が 10よりも大きくなるまでの間 i の値を表示します。do は省略可能です。

i = 0
until i > 10 do
  puts i
  i += 1
end

下記の例も同じように動作します。

i = 0
begin
  puts i
  i += 1
end until i > 10

~のあいだ(for, in, do)

文法
for var[, var]... in expr [do]
  expression...
end

for は配列の各要素に対して処理を繰り返します。do は省略可能です。

for i in [1, 2, 3] do
  puts i                  #=> 1, 2, 3
end

下記の例では、1~10 の間処理を繰り返します。

for i in 1..10 do
  puts i                  #=> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
end

複数の配列を扱うには次のようにします。

for i, j in [[1, 2], [3, 4], [5, 6]] do
  puts i * j              #=> 2, 12, 30
end

ただし、Ruby では for 文を使用することはあまりなく、下記の様なイテレータを使用するのが一般的です。

10.times do |i|
  puts i
end

~の場合(case, when)

文法
case [expr]
[when expr[, expr]...[, *expr] [then]
  expression...]...
[when *expr [then]
  expression...]...
[else
  expression...]...
end

case, when, else は、値によって処理を振り分けます。次の例では、num の値が 1~3 の場合は SMALL、4~6 の場合は NORMAL、その他の場合は BIG を表示します。then は省略可能です。

num = 4
case num
when 1..3 then
  puts "SMALL"
when 4..6 then
  puts "NORMAL"
else
  puts "BIG"
end

ループを抜ける(break)

break は最も内側の while, until, for などのループ処理を抜けます。下記の例では、i が 5の時に forループを抜けます。

for i in 1..10
  if i == 5 then
    break
  end
  puts i                 #=> 1, 2, 3, 4
end

ループを繰り返す(next)

next は while, until, for などのループ処理において、残りの処理をスキップして次のループを始めます。次の例では、i が 5の時のみ、puts を実行しません。

for i in 1..10
  if i == 5 then
    next
  end
  puts i              #=> 1, 2, 3, 4, 6, 7, 8, 9, 10
end

ループを繰り返す(redo)

redo も next と同様、ループを繰り返しますが、next がループの終了判断を行ってから処理を行うのに対し、redo は終了判断無しで処理を繰り返します。

i = 0
while i < 5 do
  i += 1
  if i == 5 then
    redo
  end
  puts i              #=> 1, 2, 3, 4, 6
end

例外処理(raise, begin, rescue, else, ensure)

文法
raise [error_type,] message[, traceback]
文法
begin
  expression...
[rescue [error_type, ...] [=> evar] [then]
  expression...]...
[else
  expression...]...
[ensure
  expression...]
end

raise は、エラー発生時に例外(Exception)を投げます。rescue には、例外を受け取った際の例外処理を記述します。

def square(n)
  if n > 10 then
    raise RangeError, "ERROR!"   # 例外を投げる
  end
  return n * n                    # この行は実行されない
end

begin
  x = square(15)                  # 例外発生
  puts x                          # この行は実行されない
rescue RangeError                 # 例外を受け取る
  puts "ERROR: RangeError"        # 例外処理
end

例外種別に応じて複数の rescue 節を記述できます。例外種別を省略した場合、StandardError 例外とみなされます。else にはどの rescue 節にも該当しなかった例外処理を記述します。ensure には、例外の有無に関わらず実行する処理を記述します。

def func(num)
  case num
  when 1
    raise SyntaxError, "ERROR!"
  when 2
    raise ArgumentError, "ERROR!"
  when 3
    raise NoMemoryError, "ERROR!"
  when 4
    raise "ERROR!"              # Same as raise StandardError, "ERROR!"
  else
    return
  end
end

begin
  func(3)
rescue SyntaxError
  puts "Rescue(SyntaxError)"
rescue ArgumentError
  puts "Rescue(ArgumentError)"
rescue                          # Same as rescue StandardError
  puts "Rescue"
else
  puts "Else"
ensure
  puts "Ensure"
end

例外種別は、Exception クラスのサブクラスとして実装されています。rescue は指定した例外種別のサブクラスすべてを待ち受けます。例えば、SyntaxError は ScriptError のサブクラスであるため、下記の例では Rescue(SyntaxError) ではなく、Rescue(ScriptError) が表示されます。

begin
  raise SyntaxError, "ERROR!"
rescue ScriptError
  puts "Rescue(ScriptError)"     # こちらが出力される
rescue SyntaxError
  puts "Rescue(SyntaxError)"     # こちらにはマッチしない
end

例外種別のクラス階層は次のようになっています。

Exception
  fatal
  SystemExit
  NoMemoryError
  ScriptError
    LoadError
    NotImplementedError
    SyntaxError
  SignalException
    Interrupt
  StandardError
    ArgumentError
    IOError
      EOFError
    IndexError
      StopIteration
    LocalJumpError
    NameError
      NoMethodError
    RangeError
      FloatDomainError
    RegexpError
    RuntimeError
    SecurityError    # Ruby 1.9からはExceptionのサブクラス
    SystemCallError
      Errno::EXXXXX
    SystemStackError
    ThreadError
    TypeError
    ZeroDivitionError

Copyright(C) 2014 杜甫々
初版:2014年12月30日、最終更新:2014年12月30日
http://www.tohoho-web.com/ruby/control.html