2010-02-18 29 views
17

यदि कोई ब्लॉक बंद है, तो यह कोड क्यों काम नहीं करता है, और यह कैसे काम करता है?क्लोजर काम नहीं करता

def R(arg) 
    Class.new do 
    def foo 
     puts arg 
    end 
    end 
end 

class A < R("Hello!") 
end 

A.new.foo #throws undefined local variable or method `arg' for #<A:0x2840538> 
+0

कर सकते हैं आप define_method है, जो एक ब्लॉक लेता है साथ def की जगह हैं, तो आप परिणाम आप चाहते हैं देखेंगे हम आपके त्रुटि संदेश देखते हैं? – samoz

+0

नमूना में त्रुटि संदेश टिप्पणी अधीन है। – yukas

+0

@Earlz, संपादन के लिए धन्यवाद। – yukas

उत्तर

26

ब्लाकों बंद कर रहे हैं और argClass.new ब्लॉक के अंदर वास्तव में उपलब्ध है। यह foo विधि के अंदर उपलब्ध नहीं है क्योंकि def एक नया दायरा शुरू करता है।

def R(arg) 
    Class.new do 
     define_method(:foo) do 
      puts arg 
     end 
    end 
end 

class A < R("Hello!") 
end 

A.new.foo # Prints: Hello! 
+0

पैरामीटर लेने वाली विधि को कैसे परिभाषित किया जाएगा? – Geo

+2

@ जीओओ: एक ब्लॉक का उपयोग करना जो पैरामीटर लेता है। जैसे 'define_method (: add_one) करें | x | एक्स + 1 एंड' – sepp2k

5

आप वर्ग को गतिशील परिभाषित हैं, तो आप इसे के रूप में आप की तरह बदल सकता है:

def R(arg) 
    c = Class.new 

    # Send the block through as a closure, not as an inline method 
    # definition which interprets variables always as local to the block. 
    c.send(:define_method, :foo) do 
    arg 
    end 

    c 
end 

class A < R("Hello!") 
end 

puts A.new.foo.inspect 
# => "Hello!" 
संबंधित मुद्दे