रूबी वर्ग प्रकार और केस स्टेटमेंट


135

दोनों के बीच क्या अंतर है

case item.class
when MyClass
  # do something here
when Array
  # do something different here
when String
  # do a third thing
end

तथा

case item.class
when MyClass.class
  # do something here
when Array.class
  # do something different here
when String.class
  # do a third thing
end

किसी कारण से, इनमें से पहला काम कभी-कभी होता है और दूसरा नहीं होता है, और दूसरी बार, दूसरा काम करता है और पहला काम नहीं करता है। क्यों? इसे करने के लिए कौन सा "उचित" तरीका है?


1
स्ट्रिंग एक वर्ग है। एक वर्ग का वर्ग वर्ग है।
वोल्ट

ध्यान दें कि यदि इसका एक उदाहरण है, यह जांचने के लिए मॉड्यूल # === विधि MyClass === objका उपयोग करता है । objMyClass
सर्जियो

जवाबों:


234

तुम्हें अवश्य उपयोग करना चाहिए:

case item
when MyClass
...

मुझे एक ही समस्या थी: "मामले में जब" : Errno :: ECONNRESET वर्ग को कैसे पकड़ा जाए?


1
धन्यवाद! डुप्लिकेट करने के लिए क्षमा करें (या किसी न किसी प्रकार का), लेकिन कई खोजों ने उस पिछले प्रश्न को चालू नहीं किया। ऐसा लगता है कि केस स्टेटमेंट द्वारा === का उपयोग काफी आम समस्या है, अब मैं देख रहा हूं कि यह समस्या है। यह शायद ट्यूटोरियल में और अधिक बार इंगित किया जाना चाहिए (लेकिन मैं शर्त लगाता हूं कि कई ट्यूटोरियल लेखकों को इसके बारे में पता नहीं है)।
डेज़ी सोफिया हॉलमैन

4
ActiveRecord का उपयोग करते हुए उल्लेख नहीं किया गया है कि एक चेतावनी। कक्षा तुलना पर ActiveRecord === विधि .is_a ?, का अर्थ है कि एक वर्ग के उपवर्ग केस स्टेटमेंट में सही का मूल्यांकन करेंगे। github.com/rails/rails/blob/…
जेरेमी बेकर

61

हाँ, नकीलोन सही है, आपको पता होना चाहिए कि whenक्लॉज़ में दी गई वस्तु पर थ्रीक्वेल === ऑपरेटर कैसे काम करता है । रूबी में

case item
when MyClass
...
when Array
...
when String
...

सच है

if MyClass === item
...
elsif Array === item
...
elsif String === item
...

यह समझें कि मामला एक थ्रीकल विधि कह रहा है ( MyClass.===(item)उदाहरण के लिए), और उस पद्धति को परिभाषित किया जा सकता है कि आप जो भी करना चाहते हैं, और फिर आप केस स्टेटमेंट का उपयोग परिशुद्धता के साथ कर सकते हैं


अगर मेरे पास है arr = []तो मैंने देखा कि if Array === arrसच if arr === Arrayका मूल्यांकन करेगा लेकिन झूठ का मूल्यांकन करेगा। क्या कोई कृपया समझाने में मदद कर सकता है?
डैनियल

4
=== सिर्फ एक विधि है जिसे परिभाषित किया जा सकता है कि जो कुछ भी एक वर्ग के डिजाइनर इसे करना चाहते हैं। याद रखें, यह भी, कि a === b का वास्तव में मतलब है। === b, इसलिए यदि आप a और b को चारों ओर घुमाते हैं, तो आप भिन्न व्यवहार प्राप्त कर सकते हैं। इस बात की कोई गारंटी नहीं है कि === सराहनीय है। वास्तव में, Array === Array गलत है, लेकिन Object === Object true है, इसलिए Array === के शब्दार्थ को पुनर्परिभाषित कर रहा है।
फ्रेड

13

आप उपयोग कर सकते हैं:

case item.class.to_s
    when 'MyClass'

... जब निम्नलिखित मोड़ संभव नहीं है:

case item
    when MyClass

इसका कारण यह है कि ऑपरेटर जिस संबंधcase का उपयोग करता है ===, और जो संबंध ===बताता है, वह सराहनीय नहीं है । उदाहरण के लिए, 5एक है Integer, लेकिन Integerएक है 5? इस तरह से आपको case/ के बारे में सोचना चाहिए when


5

रूबी में, एक वर्ग नाम एक स्थिरांक है जो उस प्रकार के ऑब्जेक्ट को संदर्भित करता है जो Classकिसी विशेष वर्ग का वर्णन करता है। इसका मतलब है कि MyClassरूबी में कहना MyClass.classजावा में कहने के बराबर है ।

obj.classClassवर्ग का वर्णन करने वाली एक प्रकार की वस्तु है obj। यदि obj.classहै MyClass, तो (मोटे तौर पर बोल) objका उपयोग करके बनाया गया था MyClass.newMyClassएक प्रकार की वस्तु है Classजो किसी भी वस्तु के उपयोग से निर्मित है MyClass.new

MyClass.classMyClassऑब्जेक्ट का वर्ग है (यह उस प्रकार की ऑब्जेक्ट का वर्ग है जो Classकिसी भी ऑब्जेक्ट का उपयोग करके बनाया गया है MyClass.new)। दूसरे शब्दों में, MyClass.class == Class


1

यह आपके itemचर की प्रकृति पर निर्भर करता है । यदि यह किसी वस्तु का उदाहरण है, जैसे

t = 5

फिर

t.class == Fixnum

लेकिन अगर यह अपने आप में एक वर्ग है जैसे

t = Array

तो यह एक Classवस्तु होगी , इसलिए

t.class == Class

संपादित करें : कृपया "मामले में कब" में Errno :: ECONNRESET वर्ग को पकड़ने के लिए देखें ? जैसा कि मेरे जवाब के बाद से नाकिलन ने कहा कि गलत हो सकता है।


रूबी में, सब कुछ "एक वस्तु का एक उदाहरण" है।
एरिक डुमिनील
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.