2017-04-13 44 views
5

anlıyorum aynı sonuca`& block` parametresi olmayan bir metotta` & block` parametresini ve 'self get ver' parametreli bir metotta 'get self' kullanmada bir fark var mıdır?

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

ve

def a() 
    yield self 
end 

kurşun, böyle bir blok a {} olduğunu varsayarsak,.

def a(&block) 
    yield self 
end 

Bu: Ben böyle bazı kodun üzerine tökezledi beri herhangi bir fark yapar olmadığına veya (başka türlü değişken/başvuru bloğunu kullanmak istemiyorsanız) sahip herhangi bir avantajı varsa - Benim sorum i &block kullanımını anlamıyorum somut durum:

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

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

IDE ve dokümantasyon:

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

[blok argümanı] (http://ruby-doc.org/core-2.4.1/doc/syntax/methods_rdoc.html#label-Block+Argument) belgelerine farklı kullanım durumları gösterir. – Stefan

+0

@Stefan & bloğun kullanımını anlamadığım belirli bir durumu ekledim, belki bir şeyi özlüyorum, bu yüzden bir gözünüz olabilir mi? Buna ek olarak belgeleri okudum ve bu benim anlayışıma karşılık geliyor. –

+0

Açıkça kullanmayacaksanız, listeye eklemeyin. Çağırmayı daha yavaş yapar ve kafa karıştırıcıdır. – ndn

cevap

8

Aklıma gelen tek avantajı içgözlem içindir jeneratörler bundan yararlanabilir. Ancak, Ruby'nin argümanını etkilemez. Bir yöntemi çağırırken, bildirilip bildirilmediğine veya çağrıldığına bakılmaksızın bir bloğu aktarabilir veya çıkartabilirsiniz.

+1

En azından benim için, sadece iç gözlemle ilgili değil. Yöntem imzasına bakmak ve son argümanın tüm yönteme bakıp 'verim' bir yerde bulmaya kıyasla bir lider 'olduğunu biliyordum. –

1

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

ve

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

arasındaki temel fark, blk, Proc bir örneği, bir amacı, bu nedenle, diğer yöntemlere geçirilebilir olmasıdır. Aksine, bloklar nesne değildir ve bu yüzden etrafta geçirilemezler.

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"