यदि आपने पहले रूबी के अपवादों के साथ काम किया है, तो आप जानते हैं कि आप निर्दिष्ट कर सकते हैं कि कौन से अपवाद बचाए गए हैं और कौन से नहीं:
begin
raise ArgumentError
rescue ArgumentError
# Rescues the `ArgumentError`
end
... और आप शायद जानते हैं कि जब आप "माता-पिता" को बचाते हैं तो आप उसके सभी "बच्चों" को भी बचाते हैं।
begin
raise ArgumentError
rescue StandardError
# Rescues `ArgumentError`, because it inherits from
# `StandardError`
end
जब मैं "माता-पिता" और "बच्चा" कहता हूं तो मैं केवल वर्ग विरासत की बात कर रहा हूं। रूबी स्रोत कोड में कहीं गहराई में इसके बराबर कुछ है:
class ArgumentError < StandardError
...
end
एक दिलचस्प ट्रिक
यहाँ मेरा प्रश्न है:रूबी को कैसे पता चलता है कि कोई अपवाद आपके द्वारा निर्दिष्ट वर्ग से विरासत में मिला है?
सबसे स्पष्ट तरीका यह होगा कि is_a?
. का उपयोग किया जाए या kind_of?
तरीका। हम कल्पना कर सकते हैं कि यह इस तरह दिख रहा है:
if the_exception.is_a?(StandardError)
# do the rescue
end
लेकिन ऐसा होता नहीं है। इसके बजाय, रूबी अधिक दिलचस्प ===
. का उपयोग करती है ऑपरेटर।
if StandardError === the_exception
# do the rescue
end
अगर आपने कभी a === b
. का इस्तेमाल नहीं किया है , यह आमतौर पर इस प्रश्न का उत्तर देता है "क्या एक स्वाभाविक रूप से बी द्वारा परिभाषित समूह से संबंधित है"? यहां कुछ उदाहरण दिए गए हैं:
(1..10) === 5 # true
('a'..'f') === "z" # false
String === "hello" # true
String === 1 # false
/[0-9]{3}/ === "hello123" # true
/[0-9]{3}/ === "hello" # false
क्योंकि ===
==
. जैसी एक साधारण रूबी विधि है , हम इसे स्वयं परिभाषित कर सकते हैं:
class RedThings
def self.===(thing)
thing.color == :red
end
end
तो हम क्या जानते हैं? हम जानते हैं कि rescue
===
का उपयोग करता है यह निर्धारित करने के लिए कि कौन से अपवाद बचाए गए हैं। और हम जानते हैं कि हम अपना खुद का ===
. परिभाषित कर सकते हैं तरीका। इसका मतलब है कि हम एक वर्ग बना सकते हैं जो यह तय करता है कि कौन से अपवाद बचाए गए हैं:
class SevereMatcher
def self.===(exception)
exception.message =~ /severe/
end
end
begin
raise RuntimeError, "Something severe happened"
rescue SevereMatcher
# rescues all exceptions with the word "severe" in
# the message, regardless of class.
end
एक बार जब आप इस ट्रिक को जान लेते हैं, तो केवल आपकी कल्पना की सीमा होती है।
निष्कर्ष
मैं स्वीकार करूंगा:आपको कभी भी गतिशील अपवाद मिलानकर्ता बनाने की आवश्यकता नहीं हो सकती है। लेकिन यह वास्तव में एक दिलचस्प उदाहरण है कि कैसे ===
. का उपयोग करने जैसा प्रतीत होता है-तुच्छ कार्यान्वयन विवरण kind_of?
. के बजाय रूबी को और अधिक लचीला और रोचक बनाता है।