質問
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
キーワードにしたオプション起動してください return
ingるかどうかご請求います。このように思うのですっ foo
や bar
異なる出力を決定すること foo
を含む明示的な return
に Proc f
.
なんだろうけど、日本人にその理由は。
解決
Rubyには3つの構造があります:
- A block はオブジェクトではなく、
{
...}
またはdo
によって作成されます。 。end
。 - proc は、
Proc.new
またはproc
によって作成されたProc
オブジェクトです。 - A lambda は、
lambda
(またはRuby 1.8のproc
)によって作成されたProc
です。
Rubyには、何かから戻る3つのキーワードがあります。
-
return
は、メソッドまたはラムダを終了します。 -
next
は、ブロック、proc、またはラムダを終了します。 -
break
は、ブロックに渡されたメソッド、またはブロック内のプロシージャまたはラムダを呼び出したメソッドを終了します。
ラムダでは、何らかの理由で return
は next
のように動作します。 next
および break
は、 each
などのメソッドで最も一般的に使用されるため、名前が付けられています。ブロックを終了すると反復が発生します。コレクションの next 要素で再開し、 each
を終了すると、ループから break します。
foo
の定義内で return
を使用すると、ブロックまたはproc内にある場合でも、 foo
から戻ります。ブロックから戻るには、代わりに next
キーワードを使用できます。
def foo
f = Proc.new { next "return from foo from inside proc" }
f.call # control leaves foo here
return "return from foo"
end
puts foo # prints "return from foo"
他のヒント
このセマンティクス Proc
s;あるものであるとは限りませんの意味論のためのすべてのブロックとなります。同意することが少し混乱している。であり柔軟性(その一部がRubyのないスペックを除き、その実施。
の動作は定義されて Proc
実装されます。 Lambda
sうか、ご希望の場合は return
s な口 を封入方法、利用 lambdas.または、を省略 return
キーワードから Proc
.
深い調査のぼ/骨川スネ夫閉鎖 はこちら.幻想的でドラマティッexposé.
い:
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から戻らず、代わりに次のステートメントに進むことは明らかです。