2012-08-10 10 views
14

मैं एक विधि को फिर से परिभाषित करना चाहता हूं, लेकिन इससे जुड़े चेतावनी से बचें। क्या मुझे ऐसा करने के लिए undef_method या remove_method का उपयोग करना चाहिए?undef_method का उपयोग कब करें, और remove_method का उपयोग कब करें?

(हाँ, फिर से परिभाषित करने के तरीकों एक छोटे से hacky है। क्योंकि मैं कुछ Memoization है कि मैं का उपयोग करने के लिए जब इकाई परीक्षण रन किया जा रहा है करना चाहते हैं मैं यह कर रहा हूँ, लेकिन कार्यक्रम में ही चलाया जाता है जब नहीं।)

उत्तर

20

fine manual से:

undef_method (प्रतीक) स्वयं →

नामित विधि के लिए कॉल का जवाब देने से वर्तमान वर्ग को रोकता है। इसे remove_method के साथ तुलना करें, जो विशेष वर्ग से विधि को हटा देता है; रुबी अभी भी एक संभावित रिसीवर के लिए सुपरक्लास और मिश्रित मॉड्यूल खोजेगा।

तो एक remove_method इस तरह:

class CC < C 
    def m 
    end 
end 

कहाँ def m वर्ग के लिए विधि m कहते हैं, remove_method :mm निकालता है:

class CC < C 
    remove_method :m 
end 

अनिवार्य रूप से इस के विपरीत है। लेकिन, अगर सुपर क्लास में m विधि है, तो इसका उपयोग अभी भी किया जाएगा। शिकायत करने के लिए करता है, तो आपको लगता है कि कॉल करने के लिए कोशिश

class CC < C 
    def m 
     raise 'No, you cannot do that.' 
    end 
end 

तो undef_method वास्तव में विधि को दूर नहीं करता है, यह विधि एक विशेष आंतरिक झंडा कि रूबी का कारण बनता है के साथ बदलता है:

undef_method, OTOH, अधिक इस तरह है तरीका। की तरह आप एक मौजूदा विधि की जगह और को बदलने के लिए कोशिश कर रहे हैं

ध्वनि शब्दार्थ के रूप में एक हटाने एक के बाद ही जोड़ने तो remove_method शायद अधिक उपयुक्त है है। हालांकि, अगर आप पागल होना चाहते हैं और सुनिश्चित करें कि प्रतिस्थापन विधि जगह पर है, तो undef_method उपयोगी होगा; या, अगर किसी कारण से आपको एक ही स्थान पर विधि को हटाने की आवश्यकता है और इसे दूसरे में जोड़ना है, undef_method कम से कम आपको बताएगा कि आपने केवल नौकरी नौकरी की है जबकि remove_method या तो आपको सुपर क्लास के कार्यान्वयन (और संभव अजीब बग)) या एक भ्रमित NoMethodError

+0

बहुत बढ़िया स्पष्टीकरण से main.rb

एक्स। –

4

आप दो तरीकों से एक विधि को हटा सकते हैं। कठोर

Module#undef_method() 

विरासत वाले सभी विधियों को हटा देता है। kinder

Module#remove_method() 

रिसीवर से विधि निकाल देता है, लेकिन यह अकेले विरासत में मिला तरीकों पत्ते।

2 नीचे देखें सरल उदाहरण -

उदाहरण 1 undef_method

class A 
    def x 
     puts "x from A class" 
    end 
end 

class B < A 
    def x 
     puts "x from B Class" 
    end 
    undef_method :x 
end 

obj = B.new 
obj.x 

परिणाम का उपयोग कर - main.rb: # के लिए ': undefined method में एक्स '(NoMethodError)

: 15

उदाहरण 2 का उपयोग 2 हटाने_method

class A 
    def x 
     puts "x from A class" 
    end 
end 

class B < A 
    def x 
     puts "x from B Class" 
    end 
    remove_method :x 
end 

obj = B.new 
obj.x 

परिणाम - $ गहरे लाल रंग का एक वर्ग

संबंधित मुद्दे