2010-01-07 29 views
10

मुझे वास्तव में इनके लिए एक साइन उपयोग नहीं दिख रहा है। पहले से ही rescue और raise है, तो throw और catch की आवश्यकता क्यों है? ऐसा लगता है कि उन्हें गहरे घोंसले से बाहर निकलने के लिए इस्तेमाल किया जाना चाहिए, लेकिन यह सिर्फ मेरे लिए एक गेटो की तरह गंध करता है। क्या इनके लिए अच्छे, साफ उपयोग के कोई उदाहरण हैं?रूबी में कैच और फेंक कहाँ हैं?

उत्तर

6

नोट: ऐसा लगता है कि कुछ चीजें 1.9 में पकड़/फेंक के साथ बदल गई हैं। यह उत्तर रुबी 1.9 पर लागू होता है।

एक बड़ा अंतर यह है कि आप throw कुछ भी नहीं कर सकते हैं, न कि StandardError से ली गई चीजें, raise के विपरीत। इस तरह कुछ मूर्खतापूर्ण कानूनी है, उदाहरण के लिए:

throw Customer.new 

लेकिन यह बहुत सार्थक नहीं है। लेकिन आप ऐसा नहीं कर सकते:

irb(main):003:0> raise Customer.new 
TypeError: exception class/object expected 
    from (irb):3:in `raise' 
    from (irb):3 
    from /usr/local/bin/irb:12:in `<main>' 
+0

उदाहरण बचाव/raise के साथ भी कानूनी है। यह सिर्फ "खंड या मॉड्यूल बचाव खंड के लिए आवश्यक" कहता है। –

+0

इसके अलावा, यह मुझे बता रहा है कि आप केवल एक प्रतीक को पकड़/फेंक सकते हैं। –

+0

@jleedev »रूबी का कौन सा संस्करण आप चल रहे हैं? [संपादित करें: ओह, मैंने जो कहा वह गलत है। मैंने बुरी तरह से अंतिम वाक्य टाइप किया, ठीक हो जाएगा।] –

2

यह मूल रूप से एक गोटो, और कॉल/सीसी के समान थोड़ा अधिक है, सिवाय इसके कि नियंत्रण प्रवाह को पैरामीटर के रूप में स्पष्ट रूप से नाम से स्पष्ट रूप से नामित किया जाता है। फेंक/पकड़ और raise/बचाव के बीच का अंतर यह है कि पूर्व का उद्देश्य केवल असाधारण परिस्थितियों के बजाय नियंत्रण प्रवाह के लिए किया जाना है, और यह एक स्टैक ट्रेस को एक साथ रखने में समय बर्बाद नहीं करता है।

सिनात्रा HTTP त्रुटि कोड के लिए फेंक/पकड़ का उपयोग करता है, जहां एक हैंडलर एक संरचित तरीके से सिनात्रा पुस्तकालय में सीडी नियंत्रण में फेंकने का उपयोग कर सकता है। HTTP ढांचे के अन्य प्रकार अपवादों का उपयोग करते हैं, या प्रतिक्रिया के एक अलग वर्ग को वापस लौटते हैं, लेकिन इससे सिनात्रा (उदाहरण के लिए) इसे पकड़ने के बाद एक और अनुरोध हैंडलर आज़माएं।

1

दोनों के बीच अंतर यह है कि आप केवल 'बढ़ाने' अपवाद लेकिन 'फेंक' कर सकते हैं कर सकते हैं कुछ भी (1.9)। इसके अलावा, उन्हें एक दूसरे के साथ फिर से लिखना संभव होना चाहिए, जैसा कि @ जॉन-फेमिनेला द्वारा दिए गए उदाहरण की तरह है।

5

वे जटिल मामले के लिए आवश्यकता के बिना डीएसएल से बाहर नियंत्रण गुजर/द्वारा अंत उपयोगकर्ताओं के लिए DSLs को सरल बनाने में वास्तव में उपयोगी हो सकता है अगर बयान

मैं जो उपयोगकर्ताओं को एक के माध्यम से इसे विस्तार करने के लिए अनुमति देता है एक रूबी एप्लिकेशन है, आंतरिक डीएसएल डीएसएल में कुछ कार्यों को मेरे आवेदन के विशिष्ट हिस्सों पर नियंत्रण वापस करने की आवश्यकता है। आइए एक साधारण उदाहरण लें। मान लीजिए उपयोगकर्ता दिनांकों

if today is a holiday then 
    do nothing 
end 

week_of_year = today.week.number 

if week_of_year < 10 then 

... 

do nothing बिट थ्रो जो कार्यकारी बयान से बाहर नियंत्रण गुजरता से चलाता है और मेरे पास वापस विषय में एक सरल विस्तार विकसित कर रहा है।

डीएसएल निष्पादित करने के बजाय, कुछ स्थितियों पर, हम चाहते हैं कि यह बाहर निकलें और मेरे आवेदन पर वापस नियंत्रण रखें। अब आप उपयोगकर्ता को कथन के बहुत सारे एम्बेडेड का उपयोग करने के लिए प्राप्त कर सकते हैं और डीएसएल स्वाभाविक रूप से अंत कर सकते हैं, लेकिन यह सिर्फ यह बताता है कि तर्क क्या कहने का प्रयास कर रहा है।

फेंक वास्तव में एक गोटो है जिसे 'खतरनाक माना जाता है' लेकिन कभी-कभी यह सबसे अच्छा समाधान होता है।

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