LoginSignup
34
14

More than 5 years have passed since last update.

Rubyのメソッドでreturnを省略できる時とできない時

Posted at

TL,DR

  1. Rubyのメソッドの戻り値でreturnを省略できるのは、メソッドの最後に記述した式が戻り値になるという仕様を利用したもの
  2. returnを省略した場合、その後の行に式を書くとその値が戻り値として評価されてしまう
  3. 明示的にreturnを書くとそのreturnに渡した式が戻り値になり、その後の値は評価されない

returnがない場合のメソッドの戻り値

Rubyではメソッドの戻り値はreturnに渡した値、もしくはメソッドの最後に記述した式の値を返します。

メソッドの戻り値は return に渡した値です。return が呼び出されなかった場合は、 body の最後の式の値を返します。 body の最後の式が値を返さない式の場合は nil を返します。

https://docs.ruby-lang.org/ja/latest/doc/spec=2fdef.html#eval_method

またRubyのif式ブロックでは条件式での判定結果がfalseでelseブロックを省略した場合、nilを返却します。

if 式は、条件が成立した節(あるいは else 節)の最後に評価した式の結果を返します。else 節がなくいずれの条件も成り立たなけれ ば nil を返します。

https://docs.ruby-lang.org/ja/latest/doc/spec=2fcontrol.html#if

それらを踏まえた上で下記のメソッドを見てください。

returnを省略したメソッド例1

def num_is_zero? num
  if num == 0
    "num is zero!"
  end
end

p num_is_zero? 0
# > "num is zero!"
p num_is_zero? 1
# > nil

この例では、メソッドの引数として与えられた値が0なら条件式に合致するため、if式ブロックの中の式の値が評価され、その後のメソッド内で評価される式がないため、if式ブロックの値が最終的なメソッドの戻り値として評価されます。

次の例ではif式ブロックの後に式がある場合です。

returnを省略したメソッド例2

def num_is_zero? num
  if num == 0
    "num is zero!"
  end
  "num is not zero!"
end

p num_is_zero? 0
# > "num is not zero!"
p num_is_zero? 1
# > "num is not zero!"

これはちょっと予想外に感じるかもしれませんが、メソッドの戻り値はreturnがない場合、最後に記述した式の値が評価されるという仕様のためです。引数が0の場合は一度はif式ブロック内の"num is zero!"という値が評価されますが、その後は"num is not zero!"という値が評価されてしまうため、最終的に"num is not zero!"という値が戻り値として評価されます。

これを避けるためには明示的にreturnで値を返却する、もしくは戻り値の後に式を記述しないということに気をつける必要があります。

明示的にreturnしたメソッド例

def num_is_zero? num
  if num == 0
    return "num is zero!"
  end
  "num is not zero!"
end

p num_is_zero? 0
# > "num is zero!"
p num_is_zero? 1
# > "num is not zero!"

この例では明示的にreturnした為、引数として与えられた値が0の場合はif式ブロックの"num is zero!"が戻り値として評価され、それ以降の式は評価されません。引数が0以外の場合はif式ブロックでnilの値が評価された後に"num is not zero!"が評価されるのでこの値が戻り値になります。

今回のようなif式で判定後に値を返すメソッドの場合は、if式でfalse判定後の処理をelseを省略してendの後に書くのではなく、elseブロックに値を記述する方が明瞭に書けます。

elseでfalse時の値を明記した場合

def num_is_zero? num
  if num == 0
    "num is zero!"
  else
    "num is not zero!"
  end
end

p num_is_zero? 0
# > "num is zero!"
p num_is_zero? 1
# > "num is not zero!"

まとめ

RubyやRailsでよく見かけるメソッドの戻り値のreturn省略はメソッドの最後の式の値が戻り値として評価されるという仕様を利用したものであることを念頭に置くこと。
その為、明示的にreturnしたメソッドからreturnを省略する場合は戻り値を返した後の行に式が存在しないことを確認すること。

34
14
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
34
14