def foo
f = Proc.new { return "return from foo from inside proc" }
f.call # control leaves foo here
return "return from foo"
end
def bar
b = Proc.new { "return from bar from inside proc" }
b.call # control leaves bar here
return "return from bar"
end
puts foo # prints "return from foo from inside proc"
puts bar # prints "return from bar"
return
キーワードはRubyでオプションであり、リクエストするかどうかに関係なく、常にreturn
ingであると思いました。それを考えると、foo
とbar
の出力が異なるという事実によって決定されるのは驚くべきことです。 foo
には、Proc f
に明示的なreturn
が含まれています。
なぜこれが当てはまるのか誰かが知っていますか?
これはProc
sのセマンティクスです。必ずしもすべてのブロックのセマンティクスであるとは限りません。これは少し紛らわしいことに同意します。それは追加の柔軟性のためにあります(そしておそらく部分的にRubyはその実装を除いて仕様がありません)。
動作はProc
実装で定義されます。 Lambda
sの動作が異なるため、return
sを囲んでいるメソッドから終了しないようにする場合は、lambdas。または、return
からProc
キーワードを省略します。
Rubyのクロージャの詳細な調査 ここにあります 。それは素晴らしい博覧会です。
そう:
def foo
f = Proc.new {
p2 = Proc.new { return "inner proc"};
p2.call
return "proc"
}
f.call
return "foo"
end
def foo2
result = Proc.new{"proc"}.call
"foo2 (proc result is: #{result})"
end
def bar
l = lambda { return "lambda" }
result = l.call
return "bar (lambda result is: #{result})"
end
puts foo
# inner proc
puts foo2
# foo (proc result is: proc)
puts bar
# bar (lambda result is: lambda)
このように考えてください。Proc.newは、呼び出し元の関数の一部であるコードのブロックを作成するだけです。 proc/lambdaは、特別なバインディングを持つ無名関数を作成します。小さなコード例が役立ちます:
def foo
f = Proc.new { return "return from foo from inside Proc.new" }
f.call # control leaves foo here
return "return from foo"
end
と同等です
def foo
begin
return "return from foo from inside begin/end" }
end
return "return from foo"
end
したがって、戻り値が関数 'foo'から戻ることは明らかです。
対照的に:
def foo
f = proc { return "return from foo from inside proc" }
f.call # control stasy in foo here
return "return from foo"
end
(この例では使用されていないため、バインディングを無視します)と同等です。
def unonymous_proc
return "return from foo from inside proc"
end
def foo
unonymous_proc()
return "return from foo"
end
これは明らかにfooから戻らず、代わりに次のステートメントに進みます。