2012-03-22 16 views
11

मुझे अभी इस व्यवहार का सामना करना पड़ा है जिसे मैं वास्तव में समझ नहीं पा रहा हूं।रूबी मिश्रित ओवरराइड विधि स्पष्टीकरण

module M 
    def foo 
    "module_foo" 
    end 
end 

class C 
    def foo 
    "class_foo" 
    end 
    include M 
end 

puts C.new.foo 

क्यों C.new.foo वास्तव में class_foo वापसी करता है? मुझे बहुत यकीन था कि मॉड्यूल में विधि द्वारा विधि को ओवरराइड किया जाना चाहिए। एक और बात, super साथ "class_foo" जगह C.new.foo वापसी `" module_foo "

वास्तव में मॉड्यूल की तरह लग रहा है कि इससे पहले कि वर्ग उदाहरण विधि परिभाषित किया गया है किसी भी तरह शामिल किया गया है बनाता है। कृपया क्या आप स्पष्टीकरण दे सकते हैं?

उत्तर

14

प्रोग्रामिंग रूबी mixins पर अनुभाग से:

वास्तव में, मिश्रित में मॉड्यूल को प्रभावी ढंग से सुपर-क्लास के रूप में व्यवहार करते हैं।

तो आप जो अनुभव करते हैं वह सामान्य है। अपने मॉड्यूल एम अपनी कक्षा सी के एक सुपर क्लास है

इसलिए वर्ग सी में अपने foo विधि मॉड्यूल एम में foo विधि ओवरराइड करता है

+0

हे, इतना स्पष्ट। धन्यवाद!! –

3

यहाँ कैसे रूबी विधि देखने करता है:

  1. रिसीवर के सिंगलटन वर्ग;
  2. रिसीवर की कक्षा;
  3. किसी भी मॉड्यूल विधियों में शामिल हैं;
  4. रिसीवर के सुपरक्लास में दोहराना लुकअप;
  5. यदि कोई विधि बिल्कुल नहीं मिली, तो method_missing कॉल;

आप अधिक विवरण यहाँ पा सकते हैं: http://ruby-metaprogramming.rubylearning.com/html/ruby_metaprogramming_2.html

इसलिए, एक विधि को खोजने के लिए, रूबी रिसीवर की कक्षा में चला जाता है, और जब तक यह विधि पाता है उसे वहाँ से पूर्वजों श्रृंखला चढ़ते हैं। इस व्यवहार को "दाईं ओर एक कदम, फिर ऊपर" नियम भी कहा जाता है: प्राप्तकर्ता के वर्ग में दाईं ओर एक कदम और फिर पूर्वजों की श्रृंखला तक, जब तक आपको विधि न मिल जाए। जब आप कक्षा में मॉड्यूल (या यहां तक ​​कि किसी अन्य मॉड्यूल में) भी शामिल करते हैं, तो रूबी अज्ञात वर्ग बनाता है जो मॉड्यूल को लपेटता है, और श्रृंखला में अज्ञात वर्ग को केवल कक्षा समेत ही शामिल करता है।

+1

method_missing सभी पूर्वजों को चलने के बाद तक चेक नहीं किया गया है – dbenhur

+0

यह ध्यान देने के लिए धन्यवाद, बस इसे ठीक करें! – andersonvom

+1

0. रिसीवर की सिंगलटन कक्षा; –

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