2011-12-14 15 views
7

करने के लिए सेट यदि मैं यह गहरे लाल रंग का कोड निष्पादित करें:रूबी: विधि बेवजह ओवरराइट और शून्य

def foo 
    100 
end 

p defined?(foo), foo 
if false 
    foo = 200 
end 
p defined?(foo), foo 

उत्पादन मैं मिलता है:

"method" 
100 
"local-variable" 
nil 

कोई क्यों foonil पर सेट है मेरे लिए व्याख्या कर सकते हैं अगर निष्पादित नहीं किया जा रहा है? क्या यह अपेक्षित व्यवहार या रूबी बग है?

+1

विधि ओवरराइट और शून्य पर सेट नहीं है के साथ वाट (https://www.destroyallsoftware.com/talks/wat) में इसके बारे में मज़ा आता है। 'foo() 'अभी भी काम करता है। क्या होता है कि एक स्थानीय चर 'foo' अस्तित्व में आया है। क्षमा करें, लेकिन मैं जवाब नहीं दे सकता कि ऐसा क्यों होता है। – Mischa

+0

मैं भी जवाब नहीं दे सकता क्यों। लेकिन यदि स्थानीय चर और विधियों के बीच कभी भी अस्पष्टता है, तो विधि के लिए 'self.foo' का उपयोग करना सुनिश्चित करें, और चर के लिए' foo' का उपयोग करना सुनिश्चित करें। –

+0

@sawa - मैं फिर से रोलबैक नहीं करूंगा, लेकिन मुझे आपकी टिप्पणी नहीं समझती है और मुझे समझ में नहीं आता कि आपने Bmesuere के प्रश्न को क्यों बदल दिया। सवाल के साथ कुछ भी गलत नहीं है। मुझे इसे संपादित करने की आवश्यकता नहीं दिख रही है। – Mischa

उत्तर

5

असाइनमेंट के बाईं ओर नाम nil पर सेट हो जाते हैं, भले ही कोड if false मामले में नहीं पहुंचा जा सके।

>> foo 
NameError: undefined local variable or method `foo' for main:Object 
... 
>> if false 
.. foo = 1 
.. end #=> nil 
>> foo #=> nil 

रूबी barewords को हल करने का प्रयास करता है, यह पहली स्थानीय चर के लिए लग रहा है (वहाँ कुदाल से मिट्टी खुरपना किताब है, जो मैं इस समय को खोजने के लिए नहीं कर पा रहे है कि के लिए एक संदर्भ है)। चूंकि अब आपके पास foo नामक एक है, यह nil प्रदर्शित करता है। जैसा कि मिशा ने नोट किया, विधि को अभी भी foo() कहा जा सकता है।

जब रूबी काम देखता है, यह वर्तमान क्षेत्र में चर initializes और नहीं के बराबर करने के लिए यह सेट:

+0

यदि मैं अच्छी तरह से समझता हूं, तो स्थानीय 'foo' चर बनाया जाता है जबकि रूबी कोड को पार करती है, भले ही वह कोड कभी निष्पादित न हो? – bmesuere

+2

जब तक चर एक असाइनमेंट के बाईं ओर है, हां। बीटीडब्लू: चूंकि आप एसओ के लिए नए हैं, शिष्टाचार यहां सहायक उत्तरों को अपवर्तित करना और/या स्वीकार करना है। यदि आपके पास और प्रश्न हैं, तो मुझे अपना जवाब अपडेट करने में खुशी होगी। –

+0

मुझे खेद है, मैं अपनी पिछली टिप्पणी में बहुत स्पष्ट नहीं था। मैं पूछना चाहता था कि क्या चर पार्सिंग के दौरान केवल "आरक्षित" था, या अगर स्मृति आवंटित की गई है (जो बहुत अक्षम है)? – bmesuere

1

यह वही मेरा दोस्त और रूबी सुपर विशेषज्ञ जोश गाल कहना था है। चूंकि असाइनमेंट नहीं चला था, इसलिए उसने foo के मान को अपडेट नहीं किया था।

यदि बयान ब्लॉक जैसे दायरे को नहीं बदलते हैं। यह भी

for x in xs 

और

xs.each { |x| } 

यहाँ के बीच सबसे महत्वपूर्ण अंतर है एक और उदाहरण है:

a = 123 if a # => nil 
a # => nil 

हम if a कहने में सक्षम है क्योंकि हम a सेट नहीं नहीं होना चाहिए, लेकिन रुबी a = 123 देखता है और a प्रारंभ करता है, फिर if a परपर जाता हैnil

मैं इसे वास्तव में दुभाषिया का एक प्रश्नोत्तरी मानता हूं। गैरी Bernhardt a = a

-Josh

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