2010-10-26 9 views
12

रूबी 1.8.7 और 1.9.2 में एक ही:रूबी में, irb शुरू करने के बाद क्यों, foo.nil? अपरिभाषित त्रुटि कहते हैं, और @ foo.nil? "सच" देता है, और @@ wah.nil? फिर से त्रुटि देता है?

$ irb 

ruby-1.8.7-p302 > foo.nil? 
NameError: undefined local variable or method `foo' for #<Object:0x3794c> 
    from (irb):1 

ruby-1.8.7-p302 > @bar.nil? 
=> true 

ruby-1.8.7-p302 > @@wah.nil? 
NameError: uninitialized class variable @@wah in Object 
    from (irb):3 

क्यों उदाहरण चर एक स्थानीय और वर्ग चर से अलग व्यवहार किया?

उत्तर

17

रूबी में, सबसे अनियमित या यहां तक ​​कि गैर-मौजूदा चर nil का मूल्यांकन करते हैं।

defined? @@wah  #=> nil 
@@wah 
# NameError: uninitialized class variable @@wah in Object 

defined? QUUX  #=> nil 
QUUX 
# NameError: uninitialized constant Object::QUUX 

यह एक रेड हेरिंग है:

defined? foo  #=> nil 
local_variables #=> [] 
if false 
    foo = 42 
end 
defined? foo  #=> 'local-variable' 
local_variables #=> [:foo] 
foo    #=> nil 
foo.nil?   #=> true 

defined? @bar  #=> nil 
instance_variables #=> [] 
@bar    #=> nil 
@bar.nil?   #=> true 
# warning: instance variable @bar not initialized 

defined? $baz  #=> nil 
$baz    #=> nil 
# warning: global variable `$baz' not initialized 
$baz.nil?   #=> true 
# warning: global variable `$baz' not initialized 

यह है वर्ग पदानुक्रम चर और स्थिरांक के लिए सही नहीं है, तथापि, यह स्थानीय चर, उदाहरण चर और वैश्विक चर के लिए सच है

defined? fnord  #=> nil 
local_variables #=> [] 
fnord 
# NameError: undefined local variable or method `fnord' for main:Object 

कारण आपको यहां त्रुटि क्यों मिली है नहीं है कि प्रारंभिक स्थानीय चर nil पर मूल्यांकन नहीं करते हैं, यह टी नहीं है टोपी fnord संदिग्ध है: यह हो सकता है एक तर्क-कम संदेश डिफ़ॉल्ट रिसीवर को भेजता है (यानी। self.fnord() के समतुल्य) या स्थानीय चर fnord तक पहुंच।

आदेश है कि स्पष्ट करने के लिए, आप एक रिसीवर या एक तर्क सूची (यहां तक ​​कि खाली हो तो) रूबी बताते हैं कि यह संदेश भेजें है में जोड़ने के लिए की जरूरत है:

self.fnord 
# NoMethodError: undefined method `fnord' for main:Object 
fnord() 
# NoMethodError: undefined method `fnord' for main:Object 

या सुनिश्चित करें कि पार्सर (नहीं मूल्यांकनकर्ता) को पार्स करता है (नहीं कार्यान्वित) उपयोग करने से पहले एक काम, रूबी बताने के लिए यह एक स्थानीय चर रहा है कि:

if false 
    fnord = 42 
end 
fnord    #=> nil 

क्यों आवृत्ति चर स्थानीय और वर्ग परिवर्तनीय से अलग व्यवहार किया?

यह वास्तव में नहीं है। यह स्थानीय चर के समान व्यवहार किया जाता है। वर्ग पदानुक्रम चर वह है जो अलग-अलग व्यवहार करता है, स्थानीय चर, आवृत्ति चर और वैश्विक चर सभी व्यवहार करते हैं।

अन्य कारण हैं और नरक; वर्ग चर नहीं कर सकते हैं?

मुझे नहीं पता। उदाहरण के लिए वैरिएबल यह बहुत सुविधाजनक है, क्योंकि जावा में विपरीत, उदाहरण के लिए, जहां वर्ग परिभाषा में इंस्टेंस चर घोषित किया जाता है, इस प्रकार कक्षा के हर उदाहरण के लिए हमेशा रूबी में मौजूद होता है, उदाहरण चर को कहीं भी घोषित नहीं किया जाता है। वे जादूगर रूप से अस्तित्व में वसंत करते हैं, जैसे ही उन्हें सौंपा जाता है। चूंकि आवृत्ति चर मौजूद होने की गारंटी नहीं है, उदाहरण विधियों का उपयोग करने वाले विधियों को लिखना एक दर्द होगा यदि उन्होंने अपवाद फेंक दिया।

कक्षा पदानुक्रम चर अलग क्यों हैं, मुझे नहीं पता। शायद ऐसा इसलिए है क्योंकि कोई भी उन्हें वैसे भी उपयोग नहीं करता है, या क्योंकि वे आम तौर पर कक्षा के शरीर में शुरू होते हैं और प्रारंभ नहीं होने पर उन्हें आसानी से एक्सेस नहीं किया जाता है।

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