2017-04-13 8 views
5

私はそのようなブロックa {}があると仮定した場合、私は、同じ結果にその`&block`というパラメータを持たないメソッドで、`&block`と `yield self`を持つメソッドで` yield self`を使うのに違いはありますか?

def a(&block) 
    block.call(self) 
end 

def a() 
    yield self 
end 

リードを理解しています。私の質問は - 私はそのようないくつかのコードの上につまずいているので、(私はそうでない変数/参照ブロックを使用しない場合)を有するのいずれかの利点がある場合、それはどんな違いかどうか:

def a(&block) 
    yield self 
end 

これは、私は&blockの使用を理解していないコンクリートの場合:

def rule(code, name, &block) 
    @rules = [] if @rules.nil? 
    @rules << Rule.new(code, name) 
    yield self 
end 
+0

[ブロック引数](http://ruby-doc.org/core-2.4.1/doc/syntax/methods_rdoc.html#label-Block+Argument)のドキュメントは異なるユースケースを示しています。 – Stefan

+0

@Stefan私は&ブロックの使用を理解していない特定のケースを追加しました。多分私は何かを見逃しています。それに加えて私は文書を読んで、それは私の理解に相当します。 –

+0

明示的に使用しない場合は、リストに追加しないでください。呼び出しが遅くなり、混乱します。 – ndn

答えて

8

私は考えることができる唯一の利点は、イントロスペクションのためにある:

def foo;  end 
def bar(&blk); end 

method(:foo).parameters #=> [] 
method(:bar).parameters #=> [[:block, :blk]] 

のIDEとドキュメント発電機はこれを利用することができます。ただし、Rubyの引数渡しには影響しません。メソッドを呼び出すときは、宣言されているか呼び出されているかにかかわらず、ブロックを渡すか省略することができます。

+1

少なくとも私のために、それはイントロスペクションについてだけではありません。メソッドのシグネチャを見て、最後の引数にメソッド全体を見て、どこかに 'yield'を見つけようとするよりも、'& 'が先行するかどうかを調べる方がはるかに簡単です。 –

1

def pass_block 
    yield 
end 
pass_block { 'hi' } #=> 'hi' 

def pass_proc(&blk) 
    blk.call 
end 
pass_proc { 'hi' } #=> 'hi' 

の主な違いはProcのインスタンス、blk、すなわち、オブジェクトであるので、他のメソッドに渡すことができます。対照的に、ブロックはオブジェクトではないため、渡すことはできません。

def pass_proc(&blk) 
    puts "blk.is_a?(Proc)=#{blk.is_a?(Proc)}" 
    receive_proc(blk) 
end 

def receive_proc(proc) 
    proc.call 
end 

pass_proc { 'ho' } 
blk.is_a?(Proc)=true 
    #=> "ho" 
関連する問題