「オブジェクト指向の達人を目指す人のための公開ペアプロ会」(関連記事)で質問したreturn
の話。
return
がいるのか?
def メソッド if suica.balance < price return nil end def ... ... ... end
こんな感じでメソッドの最初にif文があって、return
は必要なのか?という質問。return
は戻り値を返すもので、if文は条件に合致した処理の結果を返すから、なくても一緒じゃないか?と思った。
結論から言うと自分が間違っていて、return
がないとその後の処理が行われてしまうのでreturn
は必要だった。
メソッド内に一つのif文だけしかない場合などはreturn
がなくても同じ結果になる。
if文の詳細:制御構造 (Ruby 2.7.0 リファレンスマニュアル)
ガード節
上のコードのように、メソッドの頭で例外処理を行うものを「ガード節」「ガード構文」などと呼ぶのだそう。
こういう使い方は意識せずやったことがあったが、意識してやっていきたい。
return
についての勘違い
なんでもまず公式リファレンスを見る癖をつけていたはずなのに、読みもせず勘違いしていたことに気づいた。手元にある入門書にも書いてあった(少なくとも2回は読んだのに)。
return
式の値を戻り値としてメソッドの実行を終了します。式が2つ以上与えられた時には、それらを要素とする配列をメソッドの戻り値とします。式が省略された場合には nil を戻り値とします。
メソッドではなくブロックを抜けると思ったのが間違い。
以前AtCoder(競技プログラミングサイト)でreturn
を使ってみたときに思い通りにならず、それ以来exit
ばかり使っていた。このとき調べるべきだった。
リファレンスによると、式を省略するとnil
を返すので、return nil
はreturn
と省略して書けるようだ。でもreturn
の後ろにnil
が隠れていることは知っておく必要がある。
exit
は全プログラム終了
exit
Rubyプログラムの実行を終了します。status として整数が与えられた場合、その値を Ruby コマンドの終了ステータスとします。デフォルトの終了ステータスは 0(正常終了)です。
return
とexit
の違い
return
は、式の値を戻り値としてメソッドの実行を終了する。
一方exit
は、その時点でプログラムを終了する。
自分が勘違いしたきっかけがどの問題だったかは覚えていないが、以前exit
を使って書いたAtCoderの問題を見てみた。
B - Multiplication 2
問題文
N 個の整数 A1,...,AN が与えられます。
A1×...×AN を求めてください。
ただし、結果が 1018 を超える場合は、代わりに-1
を出力してください。入力
入力は以下の形式で標準入力から与えられる。
N
A1 ... AN
N個の整数の掛け算をして、結果によって指定の値を出力するという問題。
自分なりのコードはこんな感じ。コードの解説はこちらの記事。ちなみに素直に計算してから出力すると時間オーバーになる。
n = gets ary = gets.split.map(&:to_i) ans = 1 if ary.include?(0) puts 0 exit end ary.each do |a| ans *= a if ans > 10**18 puts -1 exit end end puts ans
exit
が2回登場している。このexit
をreturn
に置き換えたら、動くだろうか?
n = gets ary = gets.split.map(&:to_i) ans = 1 if ary.include?(0) puts 0 return end ary.each do |a| ans *= a if ans > 10**18 puts -1 return end end puts ans
あれ、同じように動く!
リファレンスをよく見ると書いてあった。
トップレベルで return した場合はプログラムが終了します。
ということは、トップレベル(クラス構文とかの外)でのreturn
はexit
と同じようにプログラム終了ということだ(終了ステータスなどの違いはある)。
自分がreturn
を使って書こうとしたコードはどんなんだったんだろうか…うーん思い出せない。return
は戻り値を返すということを意識しすぎてreturn 〇〇〇
みたいにした記憶はある。Rubyの前に少しだけPHPを勉強していたときに、return
があってもなくても変わらないことが多いイメージがあって、よく意味も知らないままにreturn
てあんまいらないなと勝手に思い込んでしまっていたのもある(反省)。
早い段階で思い込みに気づけてよかった。
質問して間違ってたことって絶対忘れないと思うから、質問してよかった。