質問

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 キーワードにしたオプション起動してください returningるかどうかご請求います。このように思うのですっ foobar 異なる出力を決定すること foo を含む明示的な returnProc f.

なんだろうけど、日本人にその理由は。

役に立ちましたか?

解決

Rubyには3つの構造があります:

  1. A block はオブジェクトではなく、 { ... } または do によって作成されます。 。 end
  2. proc は、 Proc.new または proc によって作成された Proc オブジェクトです。
  3. A lambda は、 lambda (またはRuby 1.8の proc )によって作成された Proc です。

Rubyには、何かから戻る3つのキーワードがあります。

  1. return は、メソッドまたはラムダを終了します。
  2. next は、ブロック、proc、またはラムダを終了します。
  3. 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"

他のヒント

このセマンティクス Procs;あるものであるとは限りませんの意味論のためのすべてのブロックとなります。同意することが少し混乱している。であり柔軟性(その一部がRubyのないスペックを除き、その実施。

の動作は定義されて Proc 実装されます。 Lambdasうか、ご希望の場合は returns な口 を封入方法、利用 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から戻らず、代わりに次のステートメントに進むことは明らかです。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top