रूबी जानबूझकर आपसे कुछ त्रुटियां और अपवाद छिपाएगी।
कभी-कभी यह उपयोगी हो सकता है।
जैसे Kernel#loop
का उपयोग करते समय एक ब्लॉक के साथ विधि, loop
बंद हो जाएगा जब एक StopIteration
अपवाद उठाया गया है।
लेकिन दूसरी बार यह आपके डिबगिंग सत्रों को बहुत कठिन बना सकता है।
आइए कुछ उदाहरण देखें!
छिपा अपवाद:तुलनीय मॉड्यूल + <=> विधि
पहले उदाहरण में 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
. का समावेश मॉड्यूल, जो तुलना विधियों को जोड़ता है (जैसे ==
, <
, >
) हमारी कक्षा के लिए।
ये तुलना विधियां <=>
. पर आधारित हैं विधि।
ठीक वैसे ही जैसे एन्यूमरेबल तरीके each
. पर आधारित होते हैं विधि।
फिर :
हम दो ऑब्जेक्ट बना रहे हैं (MyObject.new
) समान मान के साथ (10
)।
ध्यान दें कि भले ही उनके मान समान हों वे अलग-अलग वस्तुएं हैं , यह महत्वपूर्ण है।
अब अगर हम इन दोनों वस्तुओं की तुलना करें mo1
और mo2
हमें false
मिलता है …
क्यों?
क्योंकि हमारे <=>
. में त्रुटि है विधि, लेकिन रूबी उस त्रुटि को छुपा रही है!
ध्यान से देखें…
क्या आप त्रुटि का पता लगा सकते हैं?
अगर आपको यह अच्छी नौकरी मिली! अगर नहीं तो ठीक है 🙂
यह रहा :
value <=> other.valuee
यह देखें valuee
?
पता चला कि हमारे पास एक टाइपो है!
आम तौर पर हमें एक NoMethodError
मिलेगा अपवाद और हमें पता चल जाएगा कि समस्या बहुत जल्दी है। लेकिन इस उदाहरण में नहीं।
अच्छी खबर यह है कि रूबी 2.3 के बाद से यह बदल गया है। अब आप त्रुटि देख सकते हैं क्योंकि यह अब छिपी नहीं है।
यदि आप अभी भी पुराने रूबी संस्करण चला रहे हैं तो अपग्रेड करने का एक अन्य कारण।
छिपा अपवाद:संख्यात्मक वस्तु + जबरदस्ती विधि
छिपे हुए अपवाद का एक अन्य उदाहरण 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
के बारे में क्या? कक्षा?
हम इंटीजर का +
बदल सकते हैं इसे लागू करने का तरीका, लेकिन शायद यह एक अच्छा विचार नहीं है 🙂
समाधान?
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 में यह व्यवहार बदल रहा है, इसलिए यह एक और छिपी हुई त्रुटि होगी, इसलिए आपको इसके बारे में चिंता करने की ज़रूरत नहीं है।
सारांश
जैसा कि आप देख सकते हैं कि ये अच्छे उदाहरण हैं कि आप अपवादों को छिपाने से क्यों बचना चाहते हैं। आप मेरी किताब रूबी डीप डाइव में अपवादों के बारे में अधिक जान सकते हैं।
यदि आप इस पोस्ट को अपने दोस्तों के साथ साझा करते हैं तो मैं आभारी रहूंगा ताकि अधिक लोग इसे देख सकें।
पढ़ने के लिए धन्यवाद!