2009-06-04 14 views

उत्तर

33

आप सशर्त असाइनमेंट के लिए देख रहे:

a ||= b # Assign if a isn't already set 

और || ऑपरेटर

a = b || 2 # Assign if b is assigned, or assign 2 
+9

यह मेरे काम में उल्लिखित कारणों से काम नहीं करेगा। दूसरे उदाहरण में झूठी को सेट करने का प्रयास करें या बी को दूसरे उदाहरण में झूठ बोलने का प्रयास करें। –

+0

सही, @ JörgWMittag। सच्चाई/झूठी से सावधान रहें! –

+0

इसके अलावा मुझे पूरा यकीन है कि आप "शून्य से असाइन नहीं कर सकते" त्रुटि प्राप्त नहीं कर सकते हैं ?? लेकिन यदि आप छोटे उत्तर – Rivenfall

5
x = b || 2 

यह (?? सी # में) सम्मिलित ऑपरेटर कहा जाता है।

+2

में ब्लॉक का मूल्यांकन करने के लिए ऑब्जेक्ट पर और नील क्लास पर कोई विधि लिख सकते हैं तो यह मेरे उत्तर में उल्लिखित कारणों से काम नहीं करेगा। उदाहरण में झूठी को बी सेट करने का प्रयास करें। –

46

रूबी में, लघु सर्किटिंग बूलियन ऑपरेटरों (||, &&, and और or) true या false, बल्कि पहले संकार्य कि पूरे अभिव्यक्ति के परिणाम को निर्धारित करता है नहीं लौटाते हैं। यह काम करता है, क्योंकि रुबी के पास सच्चाई का एक सरल विचार है। या इसके बजाय, इसका झूठ का एक आसान विचार है: nil गलत है, और स्पष्ट रूप से false गलत है। अन्य सभी सच है।

तो, के बाद से || सच है जब कम से कम अपनी ऑपरेंड में से एक सच है, और ऑपरेंड बाएं से दाएं मूल्यांकन किया जाता है, इसका मतलब है कि a || b रिटर्न a, जब a सच है। लेकिन जब a गलत है, तो अभिव्यक्ति का परिणाम पूरी तरह से b पर निर्भर है, और इस प्रकार b वापस आ गया है।

इसका मतलब है कि, क्योंकि nil गलत है, तो आप दिए गए उदाहरणों के लिए ?? के बजाय || का उपयोग कर सकते हैं। (वहाँ भी गंधा a ||= b ऑपरेटर, a || a = b की तरह काम करता है किस तरह की है, लेकिन काफी नहीं है।)

हालांकि, कि केवल काम करता है, क्योंकि आप Booleans अपने उदाहरण में उपयोग नहीं करते। आप बूलियन मान के साथ सौदा करने की उम्मीद करते हैं, तो यह है कि काम नहीं करेगा:

b = false 

x = b || 2 # x should be == false, but will be 2 

उस मामले में, आप #nil?, और एक सशर्त अभिव्यक्ति का उपयोग करना होगा:

b = false 

x = unless b.nil? then b else 2 end # x should be == 2 

या त्रिगुट सशर्त का उपयोग कर ऑपरेटर:

b = false 

x = b.nil? ? 2 : b # x should be == false 

आप, आप पाएंगे कि लपेट कर सकते हैं अप करने के लिए एक अच्छा विधि में करना चाहते हैं:

class Object 
    def _? b = nil 
    return self 
    end 
end 

class NilClass 
    def _? b = nil 
    return yield if block_given? 
    return b 
    end 
end 

b = false 

x = b._? { 2 } # x should be == false 
x = b._? 2 # x should be == false 

यह प्यारा टुकड़ा बहुरूपता, खुले वर्गों और तथ्य यह है कि nil वास्तव में एक वस्तु शून्य (विपरीत, कहते हैं, जावा, जहां null वास्तव में कुछ भी नहीं है) का प्रतिनिधित्व करता है द्वारा लाया।

+0

'ए || = बी' इतना ज्यादा नहीं है" एक || ए = बी', लेकिन बिल्कुल 'ए = ए || b'। यह सशर्त असाइनमेंट नहीं है, असाइनमेंट हमेशा होता है। – Theo

+5

@ थियो: आईएसओ रूबी भाषा विशिष्टता का वर्तमान मसौदा यही कहता है, लेकिन यह गलत है। एमआरआई, यार्वी, जेआरबी, रूबिनीस, एक्सआरबी, मैकरुबी, आयरनरुबी, रुबी.नेट, मैग्लेव, स्मॉलरुबी, टिनरब, रुबीगोलाइटली और हर दूसरे रूबी कार्यान्वयन ने कभी भी बनाया है, इसे शॉर्ट-सर्किटिंग सशर्त असाइनमेंट के रूप में कार्यान्वित करें। रुबी प्रोग्रामिंग लैंग्वेज (मैटज़ द्वारा सह-लिखित), प्रोग्रामिंग रूबी और हर दूसरी रूबी पुस्तक ने कभी भी इस तरह लिखा है। RubySpec testuite इस तरह से परीक्षण करता है। स्टैक ओवरव्लो पर कई चर्चाएं और रूबी-टॉक पर कई चर्चाएं कहती हैं। Matz खुद ऐसा कहते हैं। –

+0

पीटर कूपर के लेख के लिए अनिवार्य लिंक: http://www.rubyinside.com/what-rubys-double-pipe-or-equals-really-does-5488.html –

1

coalesce मणि है, जो आपको जितना मिलता है उतना करीब है।

nil || 5 # => 5 
false || 5 # => 5 :(
false._? 5 # => false :) 
संबंधित मुद्दे