ブロックでのnext、break、returnの動作
配列の項目を列挙するeachや、文字列の置換を行うsubなどのメソッドに渡すブロックにおいて、next、break、returnの制御文が及ぼす作用を理解するのは少し難しい。
先日、String::subに渡したブロック内でbreakを使ったために思わぬ動作となり、何が起きているのか分からない状態に陥った。
そこで調べたことを以下にまとめる。
ブロックでnextを実行すると…
nextに与えた値がブロックの戻り値となって、ブロックを呼び出したメソッドに返る。
def func s = "abcdefg".sub(/cde/) { |m| next "123" } puts "sub:#{s}\n" return "xyz" end puts "next in block for String::sub\n" puts "func:#{func}\n" ↓ next in block for String::sub sub:ab123fg func:xyz
ブロックでbreakを実行すると…
breakに与えた値がブロックを呼び出したメソッドの値となって、そのメソッドの呼び出し元に返る。
def func s = "abcdefg".sub(/cde/) { |m| break "123" } puts "sub:#{s}\n" return "xyz" end puts "break in block for String::sub\n" puts "func:#{func}\n" ↓ break in block for String::sub sub:123 func:xyz
ブロックでreturnを実行すると…
returnに与えた値がブロックを呼び出したメソッドの呼び出し元の値として返る。
def func s = "abcdefg".sub(/cde/) { |m| return "123" } puts "sub:#{s}\n" return "xyz" end puts "return in block for String::sub\n" puts "func:#{func}\n" ↓ return in block for String::sub func:123