रूबी में अपवादों को फेंकने के बीच अंतर क्या है?


167

रूबी के दो अलग-अलग अपवाद तंत्र हैं: थ्रो / कैच और रेज / रेस्क्यू।

हमारे पास दो क्यों हैं?

आपको एक का उपयोग कब करना चाहिए और दूसरे का नहीं?


"नेस्टेड लूप्स से बाहर निकलना" कई प्रोग्रामिंग भाषाओं में एक आम जरूरत है। इसके अलावा gotoमें सी / सी ++ @docwhat रूप में उल्लेख किया गया है, जावा है ब्रेक लेबल और जारी रखने के लिए । (पाइथन के पास इसके लिए एक अस्वीकृत प्रस्ताव भी है ।)
फ्रैंकलिन यू

जवाबों:


104

मुझे लगता है कि http://hasno.info/ruby-gotchas-and-caveats में अंतर का एक अच्छा स्पष्टीकरण है:

कैच / थ्रो उठाना / रेस्क्यू के समान नहीं है। कैच / थ्रो आपको ब्लॉक को एक बिंदु पर जल्दी से बाहर निकलने की अनुमति देता है जहां एक कैच को एक विशिष्ट प्रतीक के लिए परिभाषित किया गया है, बचाव को बढ़ाएं अपवाद वस्तु को शामिल करने वाला वास्तविक अपवाद हैंडलिंग सामान है।


1
जानने के लिए उत्सुक ... एक iPad से इसे पढ़ना, इसलिए उन्हें 1.9 में परीक्षण नहीं किया जा सकता है, लेकिन उनमें से कुछ गोचिया हाल के रूबी संस्करणों में मान्य नहीं हैं, है ना?
डेनिस डी बर्नार्डी

12
इसके अलावा जानने लायक: raiseबहुत महंगा है। throwनहीं है। एक लूप से बाहर निकलने के लिए throwउपयोग gotoकरने के बारे में सोचें ।
docwhat

4
@ डेनिस कौन से गोचर्स का जिक्र कर रहे हैं?
docwhat

1
लिंक टूट गया है!
morhook

प्रदर्शन अंतर के बारे में अधिक समझने के लिए रूबी कैच-थ्रो और दक्षता देखें ।
फ्रैंकलिन यू

109
  • raise, fail, rescue, और ensureसंभाल त्रुटियों , भी रूप में जाना जाता अपवाद
  • throwऔर catchहैं नियंत्रण प्रवाह

अन्य भाषाओं के विपरीत, रूबी के थ्रो और कैच अपवादों के लिए उपयोग नहीं किए जाते हैं। इसके बजाय, वे निष्पादन को जल्दी समाप्त करने का एक तरीका प्रदान करते हैं जब कोई और काम करने की आवश्यकता नहीं होती है। (ग्रिम, 2011)

नियंत्रण के प्रवाह के एक स्तर को समाप्त करना, एक whileलूप की तरह , एक सरल के साथ किया जा सकता है return। एक नेस्टेड लूप की तरह, नियंत्रण प्रवाह के कई स्तरों को समाप्त किया जा सकता है throw

हालांकि जब उठाने और बचाव का अपवाद तंत्र निष्पादन को छोड़ देता है, जब चीजें गलत हो जाती हैं, तो कभी-कभी सामान्य प्रसंस्करण के दौरान कुछ गहरी नेस्टेड निर्माण से बाहर निकलने में सक्षम होना अच्छा होता है। यह वह जगह है जहाँ पकड़ और फेंक काम में आते हैं। (थॉमस एंड हंट, 2001)

संदर्भ

  1. ग्रिम, अवधी। "फेंको, पकड़ो, उठो, बचाव ... मैं बहुत उलझन में हूँ!" RubyLearning ब्लॉग। एनपी, 11 जुलाई 2011. वेब। 1 जनवरी 2012. http://rubylearning.com/blog/2011/07/12/throw-catch-raise-rescue--im-so-confused/
  2. थॉमस, डेव, और एंड्रयू हंट। "प्रोग्रामिंग रूबी।" : व्यावहारिक प्रोग्रामर गाइड। एनपी, 2001. वेब। 29 सितंबर 2015 http://ruby-doc.com/docs/ProgrammingRuby/html/tut_exception.html

2
अवधी पोडकास्ट में नहीं लगती है।
hrdwdmrbl

2
रूबी लर्निंग लिंक काम नहीं करता है। यहां एक और ब्लॉग पोस्ट है जिसमें मतभेदों पर चर्चा की गई है: danielchangnyc.github.io/blog/2013/10/10/23/throw-raise
डेनिस

मजेदार, rubylearning.com को लगता है कि अवधी का लेख अभी भी है । मुझे लगता है कि इसलिए हम सामान को एसओ पर कॉपी करते हैं, इसलिए यह खो नहीं जाएगा!
बेरेड बेक

21

https://coderwall.com/p/lhkkug/don-t-confuse-ruby-s-throw-statement-with-raise एक उत्कृष्ट विवरण प्रस्तुत करता है, मुझे संदेह है कि मैं इसमें सुधार कर सकता हूं। जैसा कि मैंने जाना, ब्लॉग पोस्ट से कुछ कोड नमूनों को संक्षेप में प्रस्तुत करना:

  1. raise/ आप / अन्य भाषाओं (या पायथन / / ) से परिचित हैं / निर्माण rescueके निकटतम एनालॉग हैं । यदि आपको कोई त्रुटि स्थिति आई है और आप इसे किसी अन्य भाषा में समाप्त कर देंगे , तो आपको रूबी में होना चाहिए ।throwcatchraiseexceptthrowraise

  2. रूबी throw/ catchआपको निष्पादन को तोड़ने और एक catch(जैसे raise/ rescueकरता है) की तलाश में ऊपर चढ़ने देता है , लेकिन वास्तव में त्रुटि स्थितियों के लिए नहीं है। इसका उपयोग शायद ही कभी किया जाना चाहिए, और जब "संगत स्टैक को तब तक चलना है जब तक आप एक संबंधित catch" व्यवहार नहीं पाते हैं तब तक के लिए एक एल्गोरिथ्म आप लिख रहे हैं के लिए समझ में आता है, लेकिन यह throwएक त्रुटि के अनुसार के बारे में सोचने का मतलब नहीं होगा स्थिति।

    रूबी में पकड़ने और फेंकने के लिए क्या उपयोग किया जाता है? throw/ catchनिर्माण के अच्छे उपयोग पर कुछ सुझाव प्रदान करता है ।

उनके बीच ठोस व्यवहार अंतर में शामिल हैं:

  • rescue Fooके Fooउपवर्गों सहित बचाव उदाहरणों को प्रस्तुत करेगा Foocatch(foo)केवल पकड़ेगा एक ही वस्तु, Foo। न केवल आप catchइसके उदाहरणों को पकड़ने के लिए एक वर्ग नाम पारित नहीं कर सकते हैं , बल्कि यह समानता तुलना भी नहीं करेगा। उदाहरण के लिए

    catch("foo") do
      throw "foo"
    end

    आपको 2.2 से पहले UncaughtThrowError: uncaught throw "foo"(या ArgumentErrorरूबी के संस्करणों में) देगा

  • एकाधिक बचाव खंड सूचीबद्ध किए जा सकते हैं ...

    begin
      do_something_error_prone
    rescue AParticularKindOfError
      # Insert heroism here.
    rescue
      write_to_error_log
      raise
    end

    जबकि कई catches को नेस्टेड होने की आवश्यकता है ...

    catch :foo do
      catch :bar do
        do_something_that_can_throw_foo_or_bar
      end
    end
  • एक नंगे rescueके बराबर है rescue StandardErrorऔर एक मुहावरेदार निर्माण है। एक "नंगे catch", जैसे catch() {throw :foo}, कभी भी कुछ भी नहीं पकड़ेगा और इसका उपयोग नहीं किया जाना चाहिए।


अच्छी व्याख्या है, लेकिन इस सवाल का जवाब देता है कि क्यों वे धरती पर रगड़ खाएंगे = दूसरी भाषा में फेंकेंगे। और फिर फेंक भी शामिल है, लेकिन यह अन्य भाषाओं में फेंक! मैं वहां उनका मूल तर्क नहीं देख सकता
6

@ wired00 (श्रग।) मैं मानता हूं कि आज अन्य लोकप्रिय भाषाओं की तुलना में यह बहुत विलक्षण है।
मार्क अमेरी

2
@ वायर्ड00: इसे 1960 के दशक में संरचित त्रुटि हैंडलिंग के साथ पहले प्रयोगों के बाद "अपवाद" कहा जाता है, इसे सेमिनल लेखों में एक अपवाद "अपवाद" कहा जाता है, जो अपवाद हैंडलिंग के आधुनिक रूप का आविष्कार करता है, इसे कहा जाता है लिस्प्स और स्मालटाल्क्स में एक अपवाद को बढ़ाते हुए, जो रूबी के लिए कुछ मुख्य प्रेरणाएँ थीं, और इसे हार्डवेयर में एक बाधा को "बढ़ा" या "उठाना" कहा जाता है, जहां एक "प्रोग्रामिंग की अवधारणा से पहले भी अवधारणा मौजूद थी। भाषा ”अस्तित्व में है। सवाल यह होना चाहिए: अन्य भाषाओं ने उन्हें क्यों बदल दिया?
जोर्ग डब्ल्यू मित्तग

@MarkAmery: याद उन "अन्य लोकप्रिय भाषाओं" की है कि कई हैं छोटे रूबी से या कम से कम समकालीन। इसलिए, सवाल यह होना चाहिए: उन अन्य भाषाओं ने रूबी (और स्मॉलटाक और लिस्प और हार्डवेयर और साहित्य) का पालन क्यों नहीं किया।
जोर्ग डब्ल्यू मित्तग

@ JörgWMittag दिलचस्प - आपने मुझे थोड़ा ऐतिहासिक शोध करने के लिए प्रेरित किया। C ++ को रूबी के साथ आने से पहले एक अपवाद वर्ष "फेंकने" की धारणा थी, और प्रति english.stackexchange.com/a/449209/73974 शब्द वास्तव में 70 के दशक में वापस चला जाता है ... इसलिए मुझे लगता है कि हमें अभी भी रूबी की आलोचना करना है स्थापित शब्दावली ले रहा है और इसका उपयोग पूरी तरह से कुछ अलग करने के लिए करता है।
मार्क एमी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.