2012-08-22 6 views
5

जब मैं तरीकों कि एक वैकल्पिक ब्लॉक लेने के बारे में, मैं आम तौर पर की तरहइस गतिशील रूप से परिभाषित विधि में 'block_given?' क्यों काम नहीं करता है?

block.call if block_given? 

हालांकि, विधि में गतिशील रूप से नीचे एक की तरह परिभाषित किया गया, block_given? कुछ का उपयोग काम करने के लिए प्रतीत नहीं होता।

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' } 

ब्लॉक को अपेक्षित कहा जाता है, लेकिन block_given? झूठा रिटर्न देता है।

यह क्यों है?

उत्तर

9

ब्लॉक बंद हैं, इसलिए उन्हें स्थानीय चर (जैसे method_name) याद है। उन्हें ब्लॉक भी याद हैं: yield और block_given? उस ब्लॉक की तलाश में हैं जो define_method पर सक्रिय था, ब्लॉक को bar पर पास नहीं किया गया था। कोई नहीं था, इसलिए दिए गए रिटर्न को झूठा ब्लॉक करें।

इस का एक बेहतर उदाहरण

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'} 

जो आउटपुट

Was given a block? true 
block passed to create_method 
block passed to the created method 
है
संबंधित मुद्दे