2012-08-22 12 views
5

, ben genellikle işe görünmüyor Ancak yöntemde dinamik aşağıdaki gibi tanımlananNeden "block_given?" Bu dinamik olarak tanımlanan yöntemle çalışmıyor? Ben isteğe bağlı blok almak yöntemleri yazdığınızda

block.call if block_given? 

, block_given? gibi bir şey kullanın.

class Foo 
    %w[bar baz].each do |method_name| 
    define_singleton_method(method_name) do |&block| 
     puts "Was #{method_name} given a block? #{block_given?}" 
     puts block.call 
    end 
    end 
end 

Foo.bar { puts 'I am a block' } 

Blok beklendiği gibi çağrıldı, ancak block_given? yanlış döndürdü.

Bu neden?

cevap

9

Bloklar kapanır, bu nedenle yerel değişkenleri hatırlarlar (ör. method_name). Ayrıca, blokları hatırlarlar: yield ve block_given?, define_method'un çağrıldığı anda etkin olan bloğu değil, bloğun bar'a geçmesine izin vermez. Bir tane yoktu, bu yüzden verilen blok yanlış döndürür.

bu daha iyi bir gösterimidir

Was given a block? true 
block passed to create_method 
block passed to the created method 
verir

def create_method 
    define_singleton_method('foo') do |&block| 
    puts "Was given a block? #{block_given?}" 
    puts yield 
    puts block.call 
    end 
end 

create_method {'block passed to create_method'} 
foo {'block passed to the created method'} 

olduğu

İlgili konular