2013-04-19 7 views
9

मुझे समझ नहीं आता क्यों मॉड्यूल के वर्ग चर तक पहुँचने निम्न उदाहरण में विफल रहता है कर सकते हैं:मॉड्यूल और क्लास चर का उपयोग बढ़ाएं?

module M 
    @@xyz = 123 
end 
M.class_variables # [:@@xyz] 
M.class_variable_get :@@xyz # 123 , so far so good 

class C 
    extend M 
end 
C.singleton_class.class_variables # [:@@xyz] 
C.singleton_class.class_variable_get :@@xyz # NameError: 
         # uninitialized class variable @@xyz in Class 

किसी को भी व्याख्या कर सकते हैं क्यों वर्ग चर @@xyzC की सिंगलटन वर्ग में अचानक inacessible/अपरिभाषित है?

अद्यतन: मैंने उपरोक्त कोड को विभिन्न रूबी याएआरवी संस्करणों के साथ दोबारा जांच लिया और इसे नवीनतम में एक रिग्रेशन के रूप में ढूंढ लिया।

अद्यतन 2:

नवीनतम रूबी पीढ़ी में Module#class_variables विधि की परिभाषा में बदलाव किया गया था।

  • रूबी अप परिभाषा 1.9.3 के लिए

    class_variables → सरणी

    आधुनिक में वर्ग चर के नाम की एक सरणी देता है।

  • रूबी 2.0.0 नवीनतम स्थिर संस्करण

    class_variables(inherit=true) → सरणी

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

इसलिए नवीनतम रूबी अवतार में class_variables रिटर्न डिफ़ॉल्ट शामिल मॉड्यूल की भी वर्ग चर द्वारा। बस उत्सुक है कि यह सुविधा क्या है या यदि यह अभी भी include के साथ "शामिल" चिंता मॉड्यूल करता है और extend नहीं है।

क्या कोई समझा सकता है?

+1

मुझे 'c.singleton_class.class_variables' पंक्ति से' [] 'मिला। आपको परिणाम कैसे मिला? –

+0

आप किस रूबी कार्यान्वयन का उपयोग करते हैं? मेरे प्रश्न में मैंने उल्लेख किया कि इसका परीक्षण रुबी 1.9.3 और 2.0.0 के साथ किया गया था। सावा ने इस नोट को किसी ज्ञात कारण के लिए मिटा दिया। * आप पर शर्म आती है, साया *;) –

+0

मैं 'सी: \> ruby ​​-v रूबी का उपयोग कर रहा हूं 1.9.3p374 (2013-01-15) [i386-mingw32]' –

उत्तर

2

सुनिश्चित नहीं हैं कि अगर इनमें से किसी एक जवाब हैं, लेकिन मैं इन

C::M.class_variables #=> ["@@xyz"] 
# (but gives "warning: toplevel constant M referenced by C::M") 

और

class D 
    include M 
end 
D.class_variables #=> ["@@xyz"] 

(यह रूबी 1.8.7 से, बाद के संस्करण की जरूरत नहीं है मिला अभी हाथ)।

include मॉड्यूल के उदाहरण विधियों को वर्ग के उदाहरण विधियों का कारण बनता है। पिकैक्स के अनुसार, "यह लगभग है जैसे मॉड्यूल उस वर्ग का सुपरक्लास बन जाता है जो इसका उपयोग करता है"।

इस बीच, extendऑब्जेक्ट पर मॉड्यूल के तरीकों को जोड़ने का इरादा रखता है; जब कक्षा परिभाषा में कहा जाता है तो यह self.extend के बराबर है। ऐसा लगता है कि वे बराबर नहीं हैं।

एचटीएच।

+0

मैं 'शामिल' और 'विस्तार' के बीच अंतर को समझता हूं। इसे संक्षिप्त करने के लिए, सवाल यह है कि 'class_variable_get' को' [email protected]' 'वैरिएबल '@@ xyz' क्यों नहीं मिलता है, भले ही' class_variables' अपना प्रतीक वापस कर दे! –

+0

@ डेविड यूनिक 'C.singleton_class.class_variables' को '[]' देना चाहिए। –

+0

@RubyLovely शायद यह चाहिए, क्योंकि प्रलेखन द्वारा 'विस्तार' करने के लिए, इसे केवल उदाहरण विधियों को जोड़ना चाहिए। हालांकि वर्तमान रूबी यार्वी-आधारित कार्यान्वयन 1.9.एक्स और 2.0.0 मॉड्यूल विस्तारित कक्षा के साथ सिंगलटन वर्ग के '[@ @ xyz] 'लौटाते हैं। –

0

संक्षेप में, आप जो अंतर देखते हैं वह यह है कि मॉड्यूल कक्षाओं के समान काम नहीं करते हैं।मैं अपने उच्च-अप नहीं बहुत पहले करने के लिए मेरा यह सवाल किया है: Inheriting class methods from mixins

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

+0

मुझे यह मिल गया है, लेकिन फिर सिंगलटन क्लास पर 'class_variables'' क्यों कहा जाता है, "मिश्रित-इन" वर्ग चर '@@ xyz' लौटाता है? क्या यह रिपोर्ट करने के लिए एक बग उम्मीदवार है? –

+0

असल में, मुझे यह स्वीकार करना होगा कि मैंने एक सामान्य उत्तर प्रदान किया है। आपका कोड मेरी रूबी 1.9.3 पर भी वैसे ही काम नहीं करता है। उदाहरण के लिए, 'C.singleton_class.class_variables' लाइन खाली सरणी' [] 'मेरे लिए लौटती है ... –

1

यह उत्तर नहीं है, सिर्फ प्रश्न के कुछ टिप्पणियां हैं।

अगर हम वर्ग C में मॉड्यूल M में शामिल हैं, C हो जाता वर्ग चर M में परिभाषित:

module M 
    @@xyz = 123 
end 

class C 
    include M 
end 

C.class_variables #=> [:@@xyz] 
C.class_variable_get(:@@xyz) # 123 

वर्ग परिभाषा extend M कॉल करने के लिए के रूप में eigen कक्षा में include M (या सिंगलटन वर्ग) कॉल करने के लिए equivalant है उस वर्ग का।

module M 
    @@xyz = 123 
end 

eigenclass = class C 
    class << self 
    include M 
    self 
    end 
end 

eigenclass.class_variables   #=>[:@@xyz] 
eigenclass.class_variable_get(:@@xyz) #=>NameError: uninitialized class variable @@xyz in Class 

ऐसा लगता है कि रुबी सामान्य वर्गों और ईजिन वर्गों का अलग-अलग व्यवहार करते हैं।

0

विशेष कोड उदाहरण के बारे में, यह मेरी रूबी 1.9.3p194 पर अलग ढंग से काम करता है:

module M 
    @@xyz = 123 
end 
M.class_variables # [:@@xyz] 
M.class_variable_get :@@xyz # 123 , so far so good 

class C 
    extend M 
end 
C.singleton_class.class_variables # [] - HERE BE THE DIFFERENCE 
C.singleton_class.class_variable_get :@@xyz # NameError: 
बेशक

, कि wha मैं उम्मीद थी है। C.singleton_class क्लास क्लास का प्रत्यक्ष उप-वर्ग है, और कहीं भी मैंने आपको क्लास या उसके वंशजों पर किसी भी कक्षा चर सेट अप नहीं देखा है ... लेकिन मुझे विश्वास है कि कोड आपकी मशीन पर लिखने के तरीके को काम करता है।

+1

तो यह एक बग ट्रैकर को रिपोर्ट करने के लिए एक प्रतिगमन और समस्या की तरह दिखता है। –

+0

मैं पिछले रूबी संस्करणों पर परीक्षण करने जा रहा हूं और परिणामों की रिपोर्ट कर रहा हूं। –

+0

अंतर 2.0.0 संस्करण में बदलावों के कारण है। 'class_variables' भी कक्षा मॉड्यूल देता है * विरासत * शामिल मॉड्यूल से *। अभी भी उत्सुक है कि एक ही समय में '@@ xyz' विरासत में और पहुंच योग्य कैसे हो सकता है। –

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