2012-02-27 17 views
16

मैं वर्तमान कक्षा के संदर्भ में निष्पादित करने के लिए कोड लिखने के लिए class_eval का उपयोग कर रहा हूं। निम्नलिखित कोड में, मैं विशेषता मानों के परिवर्तनों के लिए एक काउंटर जोड़ना चाहता हूं। मेरे मामले में, class Foo के तहत -'class_eval` स्ट्रिंग के भीतर परिवर्तनीय दायरा क्या है?

class Class 
    def attr_count(attr_name) 
    attr_name = attr_name.to_s 
    attr_reader attr_name # create the attribute's getter 
    class_eval %Q{ 
     @count = 0 
     def #{attr_name}= (attr_name) 
     @attr_name = attr_name 
     @count += 1 
     end 

     def #{attr_name} 
     @attr_name 
     end 
    } 
    end 
    end 
class Foo 
    attr_count :bar 
end 

f = Foo.new 
f.bar = 1 

class_eval की मेरी समझ है कि यह क्रम वर्ग के संदर्भ में ब्लॉक मूल्यांकन करता है।

class Foo 
    attr_count :bar 
    @count = 0 
    def bar= (attr_name) 
    @attr_name = attr_name 
    @count += 1 
    end 

    def bar 
    @attr_name 
    end 
end 

हालांकि इसके बाद के संस्करण कोड त्रुटि हुई कह रही है, त्रुटि @count += 1 के कारण होता है: मैं ऊपर कोड रन रूप में इसी तरह की उम्मीद है। मुझे पता नहीं लगा सकता कि @count में nil:NilClass है इसके सुपर के रूप में?

(eval):5:in `bar=': undefined method `+' for nil:NilClass (NoMethodError) 

दूसरी ओर, @selman उदाहरण विधि के भीतर @count काम डाल करने के लिए एक समाधान दिया है और यह काम करता है।

class Class 
    def attr_count(attr_name) 
    #... 
    class_eval %Q{ 
     def #{attr_name}= (attr_name) 
     @attr_name = attr_name 
     if @count 
      @count += 1 
     else 
      @count = 1 
     end 
     end 
     #... 
    } 
    end 
end 

वेरिएबल स्कोप काम क्यों बदलता है? class_eval इसकी निम्न स्ट्रिंग निष्पादित कैसे करता है?

+0

आपको अपनी CS169 कक्षा कैसा लगा? :) –

उत्तर

12

यह लगभग class_eval नहीं है, यह लगभग @count है। यदि आप कक्षा के स्तर पर इस चर को परिभाषित करते हैं तो यह class instance variableinstance variable नहीं होगा।

class Class 
    def attr_count(attr_name) 
    attr_name = attr_name.to_s 
    attr_reader attr_name # create the attribute's getter 
    class_eval %Q{ 
     def #{attr_name}= (attr_name) 
     @attr_name = attr_name 
     if @count 
      @count += 1 
     else 
      @count = 1 
     end 
     end 

     def #{attr_name} 
     @attr_name 
     end 
    } 
    end 
end 

class Foo 
    attr_count :bar 
end 

f = Foo.new 
f.bar = 1 
+0

यह काम करता है। मैं 'class_eval' विधि में' @ count' और '@@ count' के बीच के अंतर से अभी भी उलझन में हूं। मेरी समझ है 1. 'class_eval' को पारित स्ट्रिंग का मूल्यांकन रनटाइम पर किया जाएगा - जब 'कक्षा फू' कहा जाता है। 2. 'फू'' के सभी उदाहरणों के लिए '@ count' एक आवृत्ति चर होना चाहिए। क्लास वैरिएबल '@@ गिनती' का उपयोग क्यों करता है यह ** आवृत्ति चर ** की तरह व्यवहार करता है? मुझे पता है कि विषय जटिल है, क्या आपके पास कुछ संदर्भ है जिसे मैं पढ़ सकता हूं? – steveyang

+0

यह [ब्लॉग पोस्ट] (http://martinfowler.com/bliki/ClassInstanceVariable.html) –

+0

हाय, @selmen। मैंने पाया कि '@@ count' वास्तव में एक आवृत्ति चर के रूप में व्यवहार नहीं करता है। यह कक्षा चर के रूप में व्यवहार करता है। ऐसा नहीं है कि मुझे – steveyang

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