2010-08-06 16 views
53

रूबी में, क्या == और के बीच अंतर === है? RDoc कहते=== बनाम == रूबी

प्रकरण समानता-के लिए वर्ग वस्तु, प्रभावी ढंग से, # == बुला लेकिन आम तौर पर वंशज द्वारा ओवरराइड सार्थक मामले बयान में अर्थ विज्ञान प्रदान करने के लिए के रूप में ही।

#==== जैसा ही है? और क्या आप बयान के मामले में कब/कैसे उपयोग किया जा सकता है इसका एक उदाहरण प्रदान कर सकते हैं?

+0

मुझे लगता है कि यहां सबसे अच्छा जवाब है http://stackoverflow.com/a/4467823/5048945 –

उत्तर

107

रूप में ही है दो वास्तव में एक दूसरे के साथ कोई लेना देना नहीं है। विशेष रूप से, #== समानता ऑपरेटर है और #=== समानता के साथ बिल्कुल कुछ भी नहीं है। व्यक्तिगत रूप से, मैं यह नहीं बल्कि दुर्भाग्यपूर्ण है कि #=== तो #== के समान दिखता है मिल जाए, का उपयोग करता है बराबर चिह्न और अक्सर मामला समानता ऑपरेटर, ट्रिपल बराबर ऑपरेटर कहा जाता है या threequals ऑपरेटर जब यह वास्तव में समानता के साथ कोई संबंध नहीं है।

मैं केस सबसमशन ऑपरेटर (यह सबसे अच्छा है जिसके साथ मैं आ सकता हूं, मैं सुझावों के लिए खुला हूं, खासकर मूल अंग्रेजी बोलने वालों से)।

a === b का वर्णन करने का सबसे अच्छा तरीका है "अगर मेरे पास a लेबल वाला एक दराज है, तो क्या इसमें b डालने का अर्थ है?"

तो, उदाहरण के लिए, Module#=== परीक्षण है कि क्या b.is_a?(a)। आप Integer === 2 है, तो यह समझ में एक लेबल किए गए बॉक्स Integer में 2 डाल करने के लिए है? हाँ यह करता है। Integer === 'hello' के बारे में क्या? बेशक नहीं।

एक और उदाहरण Regexp#=== है। यह एक मैच के लिए परीक्षण करता है। क्या /el+/ लेबल वाले बॉक्स में 'hello' डालने का अर्थ है? हाँ यह करता है।

श्रेणियों, Range#=== जैसे संग्रहों के लिए सदस्यता परीक्षण के रूप में परिभाषित किया गया है: यदि संग्रह तत्व में है तो संग्रह के साथ लेबल किए गए बॉक्स में एक तत्व डालना समझ में आता है।

तो, #=== ऐसा करता है: यह परीक्षण करता है कि रिसीवर के तहत तर्क को कम किया जा सकता है या नहीं।

case अभिव्यक्तियों के साथ क्या करना है? सरल:

case foo 
when bar 
    baz 
end 

if bar === foo 
    baz 
end 
+4

'ऐरे # ===' रूबी 1.8 या 1.9.1 में सदस्यता के रूप में परिभाषित नहीं किया गया है। 'रेंज # ===' हालांकि है। – sepp2k

+1

@ sepp2k: आप सही हैं। दस्तावेज की जांच किए बिना समझदार अर्थशास्त्र को समझने के लिए मुझे यही मिलता है। –

+0

यह मेरे लिए नया है। जानकार अच्छा लगा! – Karl

10

हां, #== द्वारा दस्तावेज़ों का मतलब है "वर्तमान ऑब्जेक्ट की उदाहरण विधि =="।

=== जैसे मामले बयान में प्रयोग किया जाता है:

case obj 
when x 
    foo 
when y 
    bar 
end 

रूप

if x === obj 
    foo 
elsif y === obj 
    bar 
end 

ही कुछ वर्गों को परिभाषित है अपने स्वयं के === रेंज (include? की तरह काम करने के लिए), क्लास (करने के लिए कर रहे हैं obj.is_a?(klass)) और Regexp की तरह अधिनियम (एक बूलियन लौटने) को छोड़कर =~ की तरह काम करने के लिए। कुछ वर्ग जो अपने === को परिभाषित नहीं करते हैं, संख्यात्मक वर्ग और स्ट्रिंग हैं।

तो

case x 
when 0 
    puts "Lots" 
when Numeric 
    puts(100.0/x) 
when /^\d+$/ 
    puts(100.0/x.to_f) 
default 
    raise ArgumentError, "x is not a number or numeric string" 
end 

if 0 == x 
    puts "Lots" 
elsif x.is_a? Numeric 
    puts(100.0/x) 
elsif x =~ /^\d+$/ 
    puts(100.0/x.to_f) 
else 
    raise ArgumentError, "x is not a number or numeric string" 
end 
+0

उत्सुक अगर आप कथन में स्ट्रिंग डालना चाहते थे, तो यह 'केस एक्स' कहने जैसा ही होगा; स्ट्रिंग -> यदि "स्ट्रिंग" == x'? – the12

+1

@12 क्या आप पूछ रहे हैं कि रूबी स्वचालित रूप से पहचानकर्ता के चारों ओर उद्धरण जोड़ देगा या वह एक टाइपो था? वैसे भी मामला एक्स; जब स्ट्रिंग' 'स्ट्रिंग === x' के बराबर होती है, जो, यदि 'स्ट्रिंग' में स्ट्रिंग है, तो' if string == x' के बराबर है। इसी प्रकार 'मामला एक्स; जब "स्ट्रिंग" '' if "स्ट्रिंग" === x' और 'if" string "== x' के बराबर है। – sepp2k

3

मज़ा तथ्य के रूप में एक ही है, === भी rescue

यहाँ में अपवाद मिलान करने के लिए प्रयोग किया जाता है एक उदाहरण है

class Example 
    def self.===(exception) 
    puts "Triple equals has been called." 
    true 
    end 
end 

raise rescue Example 
# => prints "Triple equals has been called." 
# => no exception raised 

इस का इस्तेमाल किया जाता है सिस्टम त्रुटियों से मेल खाने के लिए।

SystemCallError.=== को दोबारा सही होने पर सत्य वापस करने के लिए परिभाषित किया गया है। इस सिस्टम के साथ उसी त्रुटि संख्या के साथ त्रुटियों को कॉल करें, जैसे कि Errno::EAGAIN और Errno::EWOULDBLOCK, दोनों को केवल उनमें से एक को सूचीबद्ध करके बचाया जा सकता है।

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