2009-10-10 2 views
13

कुल न्यूब्यू प्रश्न क्षमा करें लेकिन @game_score हमेशा शून्य क्यों है?कुल नौसिखिया: रूबी में इंस्टेंस वैरिएबल?

#bowling.rb 

class Bowling 
    @game_score = 0 
    def hit(pins) 
     @game_score = @game_score + pins 
    end 

    def score 
     @game_score 
    end 
end 
+2

हां यह जावा तरीका, रुबी में आपका स्वागत है: डी – khelll

उत्तर

37

के कोड के माध्यम से चलना चलो के रूप में

अंदर डाल दिया, प्रारंभ करने की आवश्यकता, क्या हम ?

#bowling.rb 

class Bowling 
    @game_score = 0 # (1) 

इस बिंदु (1) में, हम वर्गBowling अंदर अभी भी कर रहे हैं। याद रखें: कक्षाएं किसी अन्य की तरह वस्तुएं हैं। तो, इस बिंदु पर आप क्लास ऑब्जेक्ट Bowling के आवृत्ति चर @game_scoreपर 0 असाइन कर रहे हैं।

def hit(pins) 
    @game_score = @game_score + pins # (2) 

अब (2), हम Bowling वर्ग का उदाहरण विधि के अंदर हैं। I.e: यह एक विधि है जो Bowling से संबंधित है। तो, अब इंस्टेंस वैरिएबल @game_scoreBowling क्लास से संबंधित है, न कि क्लास के लिए।

के बाद से इस उदाहरण चर कुछ भी करने के लिए प्रारंभ कभी नहीं रहा है, यह (रूबी में, अप्रारंभीकृत चर हमेशा nil का मूल्यांकन) nil करने का मूल्यांकन करेंगे, तो यह @game_score = nil + pins को मूल्यांकन करता है और nil के बाद से एक #+ विधि, इस की जरूरत नहीं है परिणामस्वरूप अपवाद उठाया जाएगा।

end 
def score 
    @game_score # (3) 

और यहाँ (3), हम Bowling वर्ग का उदाहरण विधि अंदर फिर से कर रहे हैं। यह ऊपर उल्लिखित कारणों के लिए हमेशा nil का मूल्यांकन करेगा: @game_score कभी प्रारंभ नहीं किया गया है, इसलिए यह nil का मूल्यांकन करता है।

end 
end 

हम क्या हो रहा है पर एक नज़र लेने के लिए रूबी के प्रतिबिंब क्षमताओं का उपयोग कर सकते हैं:

p Bowling.instance_variable_get(:@game_score) # => 0 
b = Bowling.new 
p b.instance_variable_get(:@game_score) # => nil 

अब चलो उदाहरण चर में कोई मान इंजेक्षन करते हैं:

b.instance_variable_set(:@game_score, 1) 
p b.score # => 1 
b.hit(3) 
p b.score # => 4 

तो, हम देखते हैं यह सब कुछ काम करता है जैसा कि हमें करना चाहिए, हमें केवल यह समझने की आवश्यकता है कि इंस्टेंस वैरिएबल प्रारंभ करने के लिए कैसे सुनिश्चित किया जाए।

ऐसा करने के लिए, हमें प्रारंभकर्ता विधि लिखने की आवश्यकता है। आश्चर्यजनक रूप से, प्रारंभिक विधि वास्तव में एक निजी उदाहरण विधिinitialize कहा जाता है। (कारण initialize एक उदाहरण विधि है, न कि क्लास विधि, वास्तव में काफी सरल है। रूबी ऑब्जेक्ट सृजन को दो चरणों में विभाजित करता है: स्मृति आवंटन और ऑब्जेक्ट प्रारंभिकता। मेमोरी आवंटन वर्ग विधि alloc नामक विधि द्वारा किया जाता है और ऑब्जेक्ट प्रारंभिक होता है उदाहरण विधि initialize कहा जाता है। (उद्देश्य-सी प्रोग्रामर इसे पहचानेंगे।) कारण alloc एक क्लास विधि है कि निष्पादन में इस बिंदु पर अभी तक कोई उदाहरण नहीं है। और कारण initialize एक है उदाहरण विधि यह है कि ऑब्जेक्ट प्रारंभिकता स्पष्ट रूप से प्रति-वस्तु है। सुविधा के रूप में, new नामक मानक फ़ैक्टरी क्लास विधि है जो आपके लिए alloc और initialize दोनों को कॉल करती है।)

class Bowling 
def initialize 
    @game_score = 0 
end 
end 

आइए परीक्षण इस:

c = Bowling.new 
p c.score # => 0 
c.hit(2) 
p c.score # => 2 

Btw: बस कुछ मामूली रूबी शैली युक्तियाँ: खरोज 2 रिक्त स्थान, नहीं 1 टैब है। और आपकी hit विधि अधिक idiomatically @game_score += pins होगी।

16

क्योंकि आप

def initialize 
    @game_score = 0 
end 

वर्ग परिभाषा काम नहीं कर रहा है आप क्या सोचते हैं यह क्या कर रहा है, और जब hit लागू हो जाता है यह nil नहीं जोड़ सकते जरूरत नहीं है।

यदि आप अब से पूछते हैं @game_score पर क्या हुआ?, अच्छी तरह से, हमेशा याद रखें कक्षा एक वस्तु और ऑब्जेक्ट एक वर्ग है।

रूबी वर्गों के इस जेन की तरह "असली" अस्तित्व है जिस तरह से यह ठंडा है। रुबी ने कक्षाओं का नाम नहीं रखा है, बल्कि कक्षा के नाम वर्ग Class की वस्तुओं के संदर्भ हैं। एक उदाहरण विधि के बाहर @game_score को असाइन करके आप क्लास इंस्टेंस चर क्लास ऑब्जेक्ट Bowling की विशेषता देते हैं, जो क्लास Class का उदाहरण है। ये वस्तुएं सामान्य रूप से बहुत उपयोगी नहीं होती हैं। (अध्याय 1, रूबी रास्ता, हैल फुल्टन देखें।)

9

@game_score परिभाषित वहाँ कहा जाता है वर्ग उदाहरण चर है, जो एक चर सिंगलटन वर्ग वस्तु के लिए परिभाषित किया गया है:

class << Bowling 
    attr_accessor :game_score 
end 

Bowling.game_score #=> 0 

यह वह जगह है जैसा कि आप सामान्य इंस्टेंस वेरिएबल से अलग ऑब्जेक्ट्स के लिए परिभाषित अलग-अलग बता सकते हैं।

0

@game_score यहां शून्य का एक मूल्य मिल कभी नहीं होगा - आप डीईएफ़ प्रारंभ @game_score = 0 अंत