2010-11-09 7 views
5

आइए कहें कि मेरे पास दो मॉड्यूल हैं। क्या एक मॉड्यूल को एक दूसरे के अंदर शामिल करना संभव है जो एक मिश्रण की तरह व्यवहार करेगा?स्थिर तरीकों के लिए काम करने के लिए मॉड्यूल मिश्रित कैसे प्राप्त करूं?

उदाहरण के लिए:

module A 
    def self.foo 
    puts "foo" 
    bar 
    end 
end 

module B 
    include A 
    def self.bar 
    puts "bar" 
    end 
end 

B.bar 
B.foo 

संपादित करें: मुझे एहसास हुआ कि मैं मूल रूप से कोड नीचे गलत कॉपी किया गया। विधियों को स्थिर होना चाहिए। सही कोड ऊपर है (और काम नहीं करता है)।

+0

मॉड्यूल कक्षाएं (मॉड्यूल.क्लास == कक्षा) हैं, जैसा कि उत्तर दिया गया है, हां। –

उत्तर

9

कक्षा विधियों को जोड़ने के बजाय विस्तार का उपयोग करें।

module A 
    module ClassMethods 
    def foo 
     puts "foo" 
     puts bar 
    end  
    end 
    extend ClassMethods  
end 

module B 
    extend A::ClassMethods 
    def self.bar 
    puts "bar" 
    end 
end 

B.bar 
B.foo 
-3

आपके द्वारा पोस्ट किया गया सटीक कोड ठीक वैसे ही काम करता है जैसा आप चाहते हैं। तो उत्तर हां है।

क्या यह वास्तव में इसे स्वयं निष्पादित करना मुश्किल होगा?

+0

+1 शायद उसके पास केवल एक टेलीलेट है और वह अतीत से इस कोड को पोस्ट कर रहा है जब रूबी पार्सर्स का अभी तक आविष्कार नहीं हुआ है। यह मेरा अनुमान कम से कम है। –

+0

@ माइक हर हर ... – juan2raid

+0

@ माइक, तो यह दुख की बात है कि हम कम से कम तेज़ी से आगे नहीं बढ़ रहे हैं ताकि हम भविष्य में रह सकें। –

18

जैसा कि आपने सीखा है कि यह काम नहीं करता है लेकिन यह क्यों काम नहीं करता है रूबी ऑब्जेक्ट मॉडल के बारे में वास्तव में एक अच्छा सबक है।

जब आप किसी ऑब्जेक्ट का उदाहरण बनाते हैं जो आपने बनाया है, उदाहरण के चर के सेट के साथ एक नई वस्तु है और ऑब्जेक्ट की कक्षा में एक पॉइंटर (और ऑब्जेक्ट आईडी जैसी कुछ अन्य चीजें और पॉइंटर superclass) लेकिन विधियों खुद वस्तु के उदाहरण में नहीं हैं। कक्षा परिभाषा में विधियों की सूची और उनके कोड (और अपनी कक्षा के लिए एक सूचक, अपने सुपरक्लास के लिए एक सूचक, और एक वस्तु आईडी) शामिल है।

जब आप किसी उदाहरण पर कोई विधि कॉल करते हैं तो रूबी इंस्टेंस की कक्षा को देखता है और उस विधि के लिए उस क्लास की विधि सूची में दिखता है। अगर इसे नहीं मिला तो यह वर्ग 'सुपरक्लास में दिखता है। अगर इसे वहां नहीं मिलता है तो यह उस वर्ग के सुपरक्लास में सुपरक्लास से बाहर होने तक दिखता है। फिर यह पहली कक्षा में वापस जाता है और एक method_missing विधि की तलाश करता है। यदि इसे कोई नहीं मिलता है तो यह सुपरक्लास पर जाता है और तब तक जब तक यह रूट ऑब्जेक्ट तक नहीं पहुंच जाता है, जहां इसे त्रुटि उत्पन्न करने के लिए डिज़ाइन किया गया है।

class Person 
    attr_accessor :dob, :name 
    def age 
    years = Time.now.year - @dob.year 
    puts "You are #{years} year#{"s" if years != 1} old" 
    end 
    def feed 
    puts "nom, nom, nom" 
    end 
end 
bubba = Person.new 
bubba.name = "Bubba" 
bubba.dob = Time.new(1983,9,26) 

वर्ग रेखाचित्र कुछ इस तरह दिखेगा:: alt text

के उदाहरण के लिए मान लीजिए कि आप एक वर्ग व्यक्ति है और आप इस तरह चर बुब्बा साथ वर्ग का एक उदाहरण करते हैं तो जब आप एक स्थैतिक विधि, कक्षा/मॉड्यूल विधि बनाते हैं तो क्या हो रहा है? खैर, याद रखें कि लगभग सबकुछ रूबी में एक वस्तु है और मॉड्यूल परिभाषा कक्षा वर्ग का एक उदाहरण है। हाँ, आपके द्वारा टाइप किया गया कोड वास्तव में एक उदाहरण भी है, यह लाइव कोड है। जब आप def self.method_name का उपयोग करके कक्षा विधि बनाते हैं तो आप उस ऑब्जेक्ट के उदाहरण में एक विधि बना रहे हैं जो कक्षा/मॉड्यूल परिभाषा है।

बढ़िया, तो उस वर्ग विधि को आप कहां परिभाषित किया जा रहा है? यह एक अज्ञात वर्ग (उर्फ सिंगलटन, ईजिन, भूत वर्ग) में परिभाषित किया जा रहा है जो इस कारण से बनाया गया है।

हमारे व्यक्ति वर्ग क्या हम इतने तरह उदाहरण बुब्बा पर एक वर्ग विधि जोड़ने अगर करने के लिए वापस जा रहे हैं:

def bubba.drive_pickup 
    puts "Yee-haw!" 
end 

कि विधि एक विशेष सिंगलटन वर्ग है कि उदाहरण के लिए अभी बनाया और सिंगलटन के सुपर क्लास है में डाल दिया जाता है अब व्यक्ति वर्ग। इससे हमारी विधि कॉलिंग श्रृंखला इस तरह दिखती है: alt text

इंस्टेंस ऑब्जेक्ट बुब्बा पर परिभाषित कोई भी अन्य विधियां भी उस सिंगलटन क्लास में रखी जाएंगी। प्रति उदाहरण ऑब्जेक्ट में एक से अधिक सिंगलटन कक्षा कभी नहीं होती है।

तो, इसे सभी कारणों से लपेटने के कारण यह क्यों काम नहीं करता है मॉड्यूल परिभाषा के उदाहरण के लिए मॉड्यूल में स्थिर तरीकों को सिंगलटन कक्षा में परिभाषित किया जा रहा है। जब आप मॉड्यूल से शामिल या विस्तार करते हैं तो आप मॉड्यूल की विधि तालिका में पॉइंटर जोड़ रहे हैं लेकिन मॉड्यूल के लिए सिंगलटन क्लास के इंस्टेंस ऑब्जेक्ट की विधि तालिका नहीं।

इस बारे में सोचें: यदि आप जेड प्रकार का उदाहरण बनाते हैं और उदाहरण के वाई के प्रकार जे को एक्स के बारे में पता होना चाहिए? नहीं, जब तक कि विशेष रूप से इसके बारे में नहीं बताया जाता। तो आपका मॉड्यूल जो किसी अन्य मॉड्यूल में मिश्रित होता है उसे किसी अन्य ऑब्जेक्ट के बारे में पता नहीं होना चाहिए जो कि पहले मॉड्यूल को अपने सुपरक्लास के रूप में होता है।

रूबी ऑब्जेक्ट मॉडल का एक बेहतर विवरण के लिए द्वारा इस भयानक मुक्त वीडियो देखने के आश्चर्यजनक बहुश्रुत Dave Thomas (कोई, वेंडी से पुरुष नहीं):
http://scotland-on-rails.s3.amazonaws.com/2A04_DaveThomas-SOR.mp4

कि वीडियो मैं डेव थॉमस की पूरी खरीदा देखने के बाद प्रोग्रामैटिक से series on the Ruby object model और यह इसके लायक था।

पीएस कोई भी मुझे भूल गए किसी भी चीज़ पर मुझे सही करने के लिए स्वतंत्र महसूस करें; विशेष रूप से किसी वस्तु में क्या है।

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

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