RubyのBreak Statementは、Proc.newv。TheAmpersand Signを使用するときに異なって振る舞うのですか?
-
29-10-2019 - |
質問
ブロックのブレークステートメント(ASに基づいて Rubyプログラミング言語)は次のように定義されています。
ブロックはそのiteratorに戻り、イテレーターはそれを呼び出した方法に戻します。
したがって、次のコードが実行されると、LocalJumperrorになります。
def test
puts "entering test method"
proc = Proc.new { puts "entering proc"; break }
proc.call # LocalJumpError: iterator has already returned
puts "exiting test method"
end
test
次のコード ではない LocalJumperrorを投げます。 Ampersand Signの特別なことは何ですか?アンパサンドは、暗黙的にproc.newを使用していませんか?
def iterator(&proc)
puts "entering iterator"
proc.call # invoke the proc
puts "exiting iterator" # Never executed if the proc breaks
end
def test
iterator { puts "entering proc"; break }
end
test
言い換えれば、私はAmpersand SignをProc.Newの呼び出しに携わる手段として読みます。その時点で、動作は最初のコードスニペットとまったく同じでなければなりません。
def iterator (p = Proc.new { puts "entering proc"; break})
...
end
免責事項: :私は言語を学んでいるNewb(Ruby 1.9.2)であるため、参照と詳細な概要を高く評価します。
解決
break
ブロックを作成します と 発信者 ブロックリターンの。次のコードで:
proc = Proc.new { break }
Procオブジェクトに変換されるブロックの「発信者」はproc.newです。 break
ブロックの発信者に戻ることになっていますが、Proc.Newはすでに返されています。
このコードで:
def iterator(&b); b.call; end
iterator { break }
ブロックの発信者はです iterator
, 、だからそれは作ります iterator
戻る。
他のヒント
これが次のとおりです 答え.
Ampersandは、Procをブロックに、ブロックをProcに変換するために使用されます。
私はあなたのケースに関連するように例を変更しました:
def run_my_code(&my_code)
puts 'before proc'
my_code.call
puts 'after proc'
end
run_my_code { puts "passing a block, accepting a proc"; break}
=> before proc
passing a block, accepting a proc
ご覧のとおり、「後のProc」に到達しませんでした
def run_my_code
yield
end
my_proc = Proc.new { puts "passing a proc instead of block"; break}
run_my_code &my_proc
=> passing a proc instead of block
LocalJumpError: break from proc-closure
from (pry):75:in `block in <main>'
2番目の例では、結果がprocがあります。 iterator
に戻ります test
関数。
def iterator(&proc)
puts 'entering iterator'
proc.call
puts 'exiting iterator'
end
def test
puts 'before test'
iterator { puts 'entering proc'; break }
puts 'after test'
end
=>before test
entering iterator
entering proc
after test
ブロック、Procs、Lambdasの違い、およびそれぞれのスコープに関係しています。
私はあなたが役に立つかもしれないと思うかもしれないという2009年にそれについての投稿を書きました: http://www.leonardoborges.com/writings/2009/07/22/procs-lambdas-blocks-whats-the-difference/
お役に立てれば。