2016-03-08 8 views
6

तक पहुंच नहीं सकता है (प्रश्न पहले से ही Ruby Forum पर पोस्ट किया गया है, लेकिन वहां कोई जवाब नहीं निकला है)।गतिशील रूप से जोड़ा गया उदाहरण विधि क्लास वेरिएबल

यह मेरा कोड है:

class MC 
    def initialize 
    @x = 5 
    @@y = 6 
    end 

    def f 
    puts @x 
    puts @@y 
    end 
end 

m = MC.new 
m.f 

m.f एक त्रुटि के बिना उम्मीद उत्पादन का उत्पादन:

5 
6 

लेकिन इस:

def m.g 
    puts @x 
    puts @@y 
end 

m.g 

पैदा करता है:

5 
warning: class variable access from toplevel 
NameError: uninitialized class variable @@y in Object 

f से @@y तक क्यों पहुंच सकता हूं, लेकिन g से नहीं?

चेतावनी में toplevel और Object का उल्लेख और त्रुटि संदेश मुझे परेशान कर रहा है।

@x5 के रूप में मुद्रित है, इसलिए इसका पर्यावरण MC है। इसमें की परिभाषा में @x और @@y की संभावना को शामिल नहीं किया गया है MC के बजाय अपूर्ण वातावरण (Object) देखें।

मुझे त्रुटि संदेश क्यों मिला?

+3

यह पहले पूछा गया था: http://stackoverflow.com/q/24510948/477037 – Stefan

+1

@Stefan: True। दुर्भाग्यवश, वहां भी कोई अच्छी व्याख्या नहीं है। –

उत्तर

4

आप कक्षा MC में g नहीं बनाते हैं, लेकिन m के सिंगलटन वर्ग (ए.के.ए. ईजेनक्लास) में।

यह विशेष रूप से m के लिए परिभाषित सिंगलटन विधियों को संग्रहीत करने के लिए ऑब्जेक्ट m ऑब्जेक्ट के लिए मौजूद एक वर्ग है।

+0

'वर्ग << मीटर; class_variable_get रखता है (: @@ y); अंत 'पूरी तरह से काम करता है। साथ ही 'def m.g; self.class.class_variable_get रखता है (: @@ y); end'। जो थोड़ा अजीब है। – mudasobwa

+0

ध्यान दें कि यह केवल उत्तर का एक हिस्सा है। सिंगलटन क्लास 'एमसी' ('m.singleton_class.superclass # => MC') का उप-वर्ग है और इस प्रकार यह" @ "y' (' m.singleton_class.class_variables # => [: @yy] 'देखता है।)। मुझे याद आ रही है कि लुकअप क्यों विफल रहता है। –

+0

मुझे लगता है कि यह एक पार्सर गड़बड़ है। – mudasobwa

5

काम ठीक नीचे स्थित सभी वेरिएंट:

def m.g; puts self.class.send(:class_eval, '@@y') end 

def m.g; puts self.class.class_variable_get(:@@y) end 

class << m; def g; puts self.class.send(:class_eval, '@@y') end end 

class << m; puts class_variable_get(:@@y) end 

लेकिन इन असफल:

def m.g; puts @@y; end 

class << m; puts class_eval('@@y') end 

मैं विचार करेंगे यह एक गहरे लाल रंग का पार्सर गड़बड़ किया जा रहा है।

+0

ध्यान दें कि विधि '# कक्षा' सिंगलटन वर्ग को छोड़ती है और 'एमसी' लौटाती है। तो पहले 3 वास्तव में आश्चर्यजनक नहीं हैं। आपको 'सिंगलटन_क्लास' के साथ वेरिएंट भी जोड़ना चाहिए जो समान व्यवहार दिखाते हैं। –

+1

निरंतर लुकअप के नियमों की तरह लगता है कि कक्षा चर पर भी लागू होता है, यानी वे स्पष्ट रूप से स्कॉप्ड हैं। – Stefan

+0

@undur_gongor 'class << m' 'सिंगलटन_क्लास' वाले वेरिएंट हैं। – mudasobwa

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