2010-02-18 8 views
13

यहां क्या हो रहा है? "जब तक" के दो रूपों के बीच सूक्ष्म अंतर क्या है?रुबी में क्यों परिभाषित नहीं किया गया है जब तक foo = true नहीं होगा? (Foo) 'असाइनमेंट करें?

> irb(main):001:0> foo = true unless defined?(foo) 
=> nil 
irb(main):002:0> unless defined?(fooo) ; fooo = false ; end 
=> false 

THX

+0

रूबी किस संस्करण का उपयोग कर रहे हैं? – bta

+1

वैरिएबल को असाइन करने की इस बात के साथ जब तक कि वे पहले ही परिभाषित नहीं हो जाते हैं, मुझे यह इंगित करने के लिए मजबूर होना पड़ता है कि 'foo || = true' एक ही चीज़ को पूरा करता है (और हमेशा' सत्य 'देता है)। –

+1

@ एलिसन आर। यदि नहीं 'foo' परिभाषित किया गया है लेकिन गलत है। – FMc

उत्तर

15

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

जब आपकी पहली पंक्ति में कोड का मूल्यांकन किया जाता है, तो यह foonil पर सेट होने के बाद से असाइनमेंट भाग निष्पादित नहीं करता है। दूसरी पंक्ति में, क्योंकि fooo अभी तक पार्स नहीं किया गया है, defined?nil को ब्लॉक निष्पादित करने के अंदर कोड देने और fooo असाइन करने देता है।

एक उदाहरण के रूप आप इस कोशिश कर सकते हैं:

if false 
    foo = 43 
end 
defined? foo 
=> "local-variable" 

यह माणिक मंच पर एक मंच post से लिया जाता है।

+0

उत्कृष्ट उदाहरण - आपके द्वारा दिखाए गए किसी भी समस्या को और सरल बनाने के बारे में सोचना चाहिए था। धन्यवाद। – farhadf

+0

जटिल व्यवहार की अच्छी व्याख्या –

-1

खैर .. एक रूप एक ब्लॉक है और एक रूप नहीं है। दूसरा भाग, ब्लॉक, अंतिम बयान का मूल्यांकन करता है। पहला .. एचआरएम .. मुझे नहीं पता कि यह वास्तव में क्या कर रहा है।

+0

-1 इसमें ब्लॉक शामिल नहीं हैं। –

-1

रूबी में 1.8.7:

foo = true unless defined?(foo) 
p foo # => nil 

unless defined?(fooo); fooo = true; end 
p foo # => nil 

मैं व्यवहार आप देख रहे हैं के लिए एक स्पष्टीकरण की जरूरत नहीं है।

+0

'fooo' ('foo' के विपरीत) सत्य है। –

2
irb(main)> foo = true unless defined?(Integer) 
=> nil 
irb(main)> foo = true unless defined?(thisIsUndefined) 
=> true 

आपका पहला ब्लॉक nil लौटा रहा है क्योंकि जिस तरह से यह पत्ते लिखा है 2 विकल्प:

  • foo परिभाषित नहीं है -> सच आवंटित
  • foo परिभाषित किया गया है -> कुछ नहीं कर

यहां, लाइन का मूल्यांकन होने पर foo को परिभाषित किया जाना चाहिए। इस प्रकार, कुछ भी नहीं होता है और nil लौटा दिया जाता है।

irb(main)> unless defined?(Integer) ; fooo = false ; end 
=> nil 
irb(main)> unless defined?(thisIsUndefined) ; fooo = false ; end 
=> false 

आपका दूसरा ब्लॉक उसी तरह से चलता है जैसा आपका पहला करता है। यदि fooo परिभाषित नहीं किया गया है, तो ब्लॉक दर्ज किया गया है और fooofalse पर सेट है। ब्लॉक की आखिरी पंक्ति का परिणाम ब्लॉक का रिटर्न वैल्यू है, इस प्रकार आप false देख रहे हैं। यदि fooo मौजूद है, तो ब्लॉक छोड़ दिया गया है और कुछ नहीं होता है, इसलिए वापसी करने के लिए कुछ भी नहीं है, इसलिए nil

आपके कोड के आधार पर, मैं कहूंगा कि foo परिभाषित किया गया था जब यह कोड चलाया गया था और fooo नहीं था (रूबी 1.8.6 में दिखाया गया परीक्षण कोड उत्पन्न हुआ था)। यदि आपने इस कोड को चलाने से पहले इनमें से किसी एक को परिभाषित नहीं किया है, तो आपके पास foo नामक कुछ हो सकता है जिसे डिफ़ॉल्ट रूप से परिभाषित किया गया है (defined?(foo) स्वयं जांचने के लिए)। एक अलग नाम का उपयोग करने का प्रयास करें और देखें कि क्या आपको एक ही परिणाम मिलते हैं।

संपादित करें:

irb(main)> defined?(bar) 
=> nil 
irb(main)> bar = true unless defined?(bar) 
=> nil 
irb(main)> defined?(bar) 
=> "local-variable" 

जाहिर है, defined?() सच लौटने के बाद से यह पहले से ही bar देखा गया है (लाइन की शुरुआत में) है, भले ही आप इसे परिभाषित करने की प्रक्रिया में हैं।

1

पहले उदाहरण में आप असाइनमेंट कथन में foo को अस्तित्व में कॉल करते हैं। हो सकता है कि यह स्पष्ट करना होगा:

bar = if true 
     puts bar.class 
     else 
     puts "not reached" 
     end 
NilClass 
=> nil 

baz = if true 
     puts baz.class 
     42 
     else 
     puts "not reached" 
     end 
NilClass 
=> 42 
12

के सरल कुछ के साथ शुरू करते हैं:

# z is not yet defined 
irb(main):001:0> defined?(z) 
=> nil 

# Even though the assignment won't execute, 
# the mere presence of the assignment statement 
# causes z to come to life. 
irb(main):002:0> z = 123 if false 
=> nil 
irb(main):003:0> defined?(z) 
=> "local-variable" 
irb(main):004:0> z 
=> nil 

अब हम अपना पहला उदाहरण यह पता लगाने कर सकते हैं।

foo = true unless defined?(foo) 

foo परिभाषित किया गया है? इससे पहले कि हम irb में ENTER दबाएं, नहीं। हालांकि, असाइनमेंट स्टेटमेंट की उपस्थिति जीवन में आने के लिए foo का कारण बनती है। इसका मतलब है कि असाइनमेंट स्टेटमेंट निष्पादित नहीं होगा, foo अस्तित्व में छोड़कर nil इसके मूल्य के रूप में होगा। और irb लाइन में अंतिम अभिव्यक्ति का मूल्यांकन क्या है? यह unless defined?(foo) है, जो nil का मूल्यांकन करता है।

असाइनमेंट (यहां तक ​​कि जो निष्पादित नहीं होते हैं) के बारे में अधिक जानकारी के लिए भिन्नताएं मौजूद हैं, Variable/Method Ambiguity की इस चर्चा को देखें। fooo परिभाषित नहीं है, तो ब्लॉक कार्यान्वित में कोड, false करने के लिए fooo की स्थापना:

अपने दूसरे उदाहरण में, वहाँ सब पर रहस्यमय कुछ नहीं है। वह असाइनमेंट अंतिम अभिव्यक्ति का मूल्यांकन किया गया है, इसलिए false हमारे ब्लॉक का वापसी मूल्य है।

1

अगस्त, सभी 1.8.7 में ठीक लग:

$ irb 
irb(main):001:0> unless defined?(fooo); fooo = true; end 
=> true 
irb(main):002:0> fooo 
=> true 
irb(main):003:0> `ruby --version` 
=> "ruby 1.8.7 (2008-06-20 patchlevel 22) [i486-linux]\n" 
संबंधित मुद्दे