2012-07-12 25 views
5

मान लीजिए कि मुझे रूबी कोड का एक अनुभाग मिला है जहां मैं एक विधि को उपनाम करना चाहता हूं (मुझे नहीं पता क्यों; चलो बस मान लें कि मेरे पास एक अच्छा कारण है)।क्या मैं रुबी में एक विधि उपनाम हटा सकता हूं?

class String 
    alias_method :contains?, :include? 
end 

यह मेरे लिए संभव है, इस धारा के बाद, करने के लिए इस अन्य नाम निकालें?

उत्तर

3
def hello 
    puts "Hello World" 
end 
alias :hi :hello 

hi #=> "Hello World" 
undef hi 
hi #=> NameError 
hello #=> "Hello World" 

संपादित करें: ध्यान दें कि यह केवल main वस्तु पर बनाया तरीकों पर काम करेंगे। इसे कक्षा में लागू करने के लिए, आपको Hello.class_eval("undef hi")

हालांकि, मेटाप्रोग्रामिंग दृष्टिकोण से कक्षाओं से निपटने के दौरान, मुझे remove_method :hi का उपयोग पसंद है क्योंकि यह विधि लुकअप का कारण बन जाएगा नीचे गिरें और एक अभिभावक वर्ग से विधि पकड़ो।

class Nums < Array 
    def include? 
     puts "Just Kidding" 
    end 
end 

n = Nums.new 
n << 4 #=> [4] 
n.include? #=> "Just kidding" 
Nums.class_eval("remove_method :include?") 
n.include? 4 #=> true 
Number.class_eval("undef include?") 
n.include? 4 #=> NoMethodError 

remove_method अधिक मेटा अनुकूल है।

+0

'hi_ मूल रूप से विरासत में मिला या मिश्रित होने पर' remove_method' बेहतर है। 'Undef' या' undef_method' का उपयोग करके कॉल को विरासत/मिश्रण-श्रृंखला में प्रचार करने से रोक दिया जाएगा। – Kelvin

+0

मैं वास्तव में यह देखने के लिए अपना जवाब संपादित कर रहा था कि आपने टिप्पणी की थी = डी –

5

remove_method ज्यादातर मामलों में काम करना चाहिए। लेकिन अगर आपका alias_method किसी मौजूदा विधि को ओवरराइट करता है, तो आपको मूल को अलग alias_method कॉल के माध्यम से सहेजने की आवश्यकता हो सकती है।

alias_method :contains?, :original_contains? 
remove_method :original_contains? # optional 

भी ध्यान दें कि एक वर्ग है कि एक से अधिक थ्रेड में इस्तेमाल को संशोधित करने की स्थिति दौड़ के लिए खतरा है:

# assuming :contains? is already a method 
alias_method :original_contains?, :contains? 
alias_method :contains?, :include? 

फिर मूल स्थिति बहाल करने के लिए। और यदि आप उपनामों का उपयोग करने से libs को अस्वीकार करने का प्रयास कर रहे हैं, तो आप इसे रोक नहीं सकते हैं यदि आप उपनाम मौजूद हैं, तो आप उन libs विधियों को बुला रहे हैं। हम रूबी 2.0 में ऐसा करने का एक तरीका देख सकते हैं: http://yehudakatz.com/2010/11/30/ruby-2-0-refinements-in-practice/

यदि आप कह सकते हैं कि आप उपनाम को क्यों हटाना चाहते हैं तो यह सहायक होगा। यदि विधि का नाम पहले मौजूद नहीं था, तो आपके बंदर-पैच द्वारा कोई अन्य libs प्रभावित नहीं होना चाहिए। साथ ही, आपको String पैच करने के बजाय String (या एक स्ट्रिंग उदाहरण में प्रतिनिधि) को उपclassing पर विचार करना चाहिए।

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