8

ブロックの break ステートメント ( The Ruby Programming Languageによる) は次のように定義されます。

これにより、ブロックがその反復子に戻り、反復子がそれを呼び出したメソッドに戻ります。

したがって、次のコードを実行すると、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 をスローしません。アンパサンド記号の特徴は何ですか? アンパサンド記号は暗黙的に 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

つまり、Proc.new 呼び出しをインライン化する手段としてアンパサンド記号を読み取ります。その時点で、動作は最初のコード スニペットとまったく同じになります。

def iterator (p = Proc.new { puts "entering proc"; break})
...
end

免責事項: 私は言語 (ruby 1.9.2) を学習したばかりなので、参照と詳細な概要を高く評価します。

4

3 に答える 3

8

breakブロックブロックの呼び出し元を返します。次のコードでは:

proc = Proc.new { break }

Proc オブジェクトに変換されるブロックの「呼び出し元」は Proc.new です。breakブロックの呼び出し元を返すはずですが、Proc.new は既に返されています。

このコードでは:

def iterator(&b); b.call; end
iterator { break }

ブロックの呼び出し元は ですiteratorので、iteratorリターンします。

于 2012-01-24T22:13:46.773 に答える
3

これが答えです。

アンパサンドは、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

ご覧のとおり、「処理後」に到達しませんでした

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があり、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
于 2012-01-17T02:43:30.300 に答える
0

これは、ブロック、プロシージャ、ラムダの違いと、それぞれのスコープに関係しています。

2009年に、役立つと思われる投稿を書きました:http: //www.leonardoborges.com/writings/2009/07/22/procs-lambdas-blocks-whats-the-difference/

お役に立てれば。

于 2012-01-17T03:22:37.913 に答える