रूबी जानबूझकर कुछ एरर्स और एक्सेप्शन्स को आपसे छिपा लेता है।
कभी-कभी यह उपयोगी हो सकता है।
जैसे Kernel#loop मेथड के साथ ब्लॉक का उपयोग करते समय, जब StopIteration एक्सेप्शन उठाया जाता है तो loop रुक जाएगा।
लेकिन अन्य समय यह आपके डिबगिंग सत्र को बहुत कठिन बना सकता है।
आइए कुछ उदाहरण देखें!
छिपा हुआ अपवाद: Comparable मॉड्यूल + <=> मेथड
पहला उदाहरण Comparable मॉड्यूल और <=> मेथड से संबंधित है।
यहाँ उदाहरण है:
class MyObject attr_accessor :value include Comparable def initialize(value) @value = value end def <=>(other) raise ArgumentError, "can't compare #{other.class} with #{self.class}" unless other.is_a?(MyObject) value <=> other.valuee end end mo1 = MyObject.new(10) mo2 = MyObject.new(10) p mo1 == mo2 आइए इस उदाहरण के बारे में बात करते हैं।
पहला:
हमारे पास MyObject नामक एक क्लास है, जिसमें एक attr_accessor value है, और Comparable मॉड्यूल का समावेश, जो हमारी क्लास में तुलना मेथड्स (जैसे ==, <, >) जोड़ता है।
ये तुलना मेथड्स <=> मेथड पर आधारित हैं।
ठीक वैसे ही जैसे Enumerable मेथड्स each मेथड पर आधारित हैं।
फिर:
हम समान मान (10) के साथ दो ऑब्जेक्ट्स (MyObject.new) बना रहे हैं।
ध्यान दें कि भले ही उनके मान समान हों वे अलग-अलग ऑब्जेक्ट्स हैं, यह महत्वपूर्ण है।
अब यदि हम इन दो ऑब्जेक्ट्स mo1 और mo2 की तुलना करते हैं तो हमें false मिलता है…
क्यों?
क्योंकि हमारे <=> मेथड में एक त्रुटि है, लेकिन रूबी उस त्रुटि को छिपा रहा है!
ध्यान से देखें…
क्या आप त्रुटि देख सकते हैं?
यदि आपने ढूंढ लिया तो बहुत बढ़िया! यदि नहीं तो कोई बात नहीं 🙂
यहाँ है:
value <=> other.valuee
यह valuee देखें?
बात यह है कि हमारे पास एक टाइपो है!
आम तौर पर हमें NoMethodError अपवाद मिलेगा और हमें पता चल जाएगा कि समस्या क्या है। लेकिन इस उदाहरण में नहीं।
अच्छी खबर यह है कि रूबी 2.3 से यह बदल गया है। अब आप त्रुटि देख सकते हैं क्योंकि यह अब छिपी नहीं है।
यदि आप अभी भी पुराने रूबी संस्करण चला रहे हैं तो अपग्रेड करने का एक और कारण।
छिपा हुआ अपवाद: न्यूमेरिक ऑब्जेक्ट + Coercion मेथड
छिपे हुए अपवाद का एक और उदाहरण Numeric ऑब्जेक्ट्स (Float, Integer) और coerce मेथड के साथ है।
यहाँ एक उदाहरण है:
class MyObject attr_accessor :value def initialize(value) @value = value end def +(other) other = MyObject.new(other) if other.kind_of?(Numeric) value + other.value end def coerce(other) mo = MyObject.new mo.valuee = other [mo, self] end end mo1 = MyObject.new 10 mo2 = MyObject.new 10 p mo1 + mo2 # 20 p mo1 + 20 # 30
यह एक और MyObject क्लास है, लेकिन नए मेथड्स, + और coerce के साथ।
coerce मेथड आपको दो असंगत प्रकारों के साथ काम करने और उन्हें एक ही प्रकार में बदलने की अनुमति देता है ताकि वे एक साथ काम कर सकें।
इस मामले में हमारी क्लास किसी न्यूमेरिक मान को दर्शाती है, जो सेकंड की संख्या, कीमत या ऐसा कुछ भी हो सकता है…
और हम इस तरह के ऑपरेशन करने में सक्षम होना चाहते हैं:
mo1 + 20 20 + mo1
पहला वाला (mo1 + 20) आसान है क्योंकि हम अपनी क्लास में + मेथड को नियंत्रित करते हैं।
लेकिन Integer क्लास का क्या?
हम Integer के + मेथड को बदलकर इसे लागू कर सकते हैं, लेकिन यह शायद अच्छा विचार नहीं है 🙂
समाधान?
अपनी खुद की क्लास में coerce मेथड को लागू करें।
Integer पर + मेथड एक चीज करेगा यह जांचना कि आपका ऑब्जेक्ट इस मेथड को लागू करता है या नहीं, और यदि करता है तो इसे कॉल करेगा।
अब, इस खंड की शुरुआत में कोड उदाहरण याद रखें?
यदि हम ऐसा करने की कोशिश करते हैं:
20 + mo1
हम 30 देखना चाहते हैं, क्योंकि mo1 का मान 10 है। लेकिन हमें यह दिखाई देता है:
MyObject can't be coerced into Fixnum
वही समस्या!
हमसे coerce मेथड के अंदर एक त्रुटि छिपाई जा रही है।
यह: mo.valuee = other
फिर से हमारे पास एक टाइपो है, लेकिन त्रुटि यह नहीं कह रही है!
MyObject can't be coerced into Fixnum
आपके लिए अच्छी खबर है, यह व्यवहार रूबी 2.5 में बदल रहा है, इसलिए यह एक और छिपी हुई त्रुटि दूर हो जाएगी ताकि आपको इसके बारे में चिंता न करनी पड़े।
सारांश
जैसा कि आप देख सकते हैं ये अच्छे उदाहरण हैं कि आप अपवादों को छिपाने से क्यों बचना चाहते हैं। आप मेरी किताब, रूबी डीप डाइव में अपवादों के बारे में अधिक जान सकते हैं।
मैं सराहना करूंगा यदि आप इस पोस्ट को अपने दोस्तों के साथ शेयर करें ताकि अधिक लोग इसे देख सकें।
पढ़ने के लिए धन्यवाद!