Computer >> कंप्यूटर ट्यूटोरियल >  >> प्रोग्रामिंग >> Ruby

रूबी एक्सेप्शन हैंडलिंग में महारत हासिल करें: एरर होने पर ऑपरेशन को रीट्राई कैसे करें

सभी एरर घातक नहीं होते। कुछ केवल यह संकेत देते हैं कि आपको फिर से प्रयास करने की आवश्यकता है। सौभाग्य से, रूबी कुछ दिलचस्प तंत्र प्रदान करता है जो "फिर से प्रयास करना" आसान बनाते हैं - हालांकि उनमें से सभी स्पष्ट या प्रसिद्ध नहीं हैं। इस पोस्ट में हम इन तंत्रों पर एक नज़र डालेंगे और वे वास्तविक दुनिया में कैसे काम करते हैं।

retry का परिचय

ठीक है - यह स्पष्ट है, लेकिन केवल अगर आप जानते हैं कि यह मौजूद है। व्यक्तिगत रूप से, मैं अपने रूबी करियर में काफी आगे बढ़ चुका था इससे पहले कि मुझे आनंददायक "retry" कीवर्ड के बारे में पता चला।

Retry रूबी के एक्सेप्शन रेस्क्यूइंग सिस्टम में अंतर्निहित है। यह काफी सरल है। यदि आप अपने रेस्क्यू ब्लॉक में "retry" का उपयोग करते हैं तो यह उस कोड खंड को फिर से चलाता है जिसे रेस्क्यू किया गया था। आइए एक उदाहरण देखें।

begin retries ||= 0 puts "try ##{ retries }" raise "the roof" rescue retry if (retries += 1) < 3 end # ... outputs the following: # try #0 # try #1 # try #2 

यहां कुछ बातें ध्यान देने योग्य हैं:

  • जब retry को कॉल किया जाता है, तो सभी कोड जो begin और rescue के बीच में है, फिर से चलाया जाता है। यह सबसे निश्चित रूप से नहीं "वहीं से शुरू होता है जहां यह छूट गया था" या ऐसा कुछ।

  • यदि आप रीट्राई को सीमित करने के लिए कोई तंत्र प्रदान नहीं करते हैं, तो आप अनंत लूप के साथ समाप्त हो जाएंगे।

  • begin और रेस्क्यू ब्लॉक दोनों में कोड पैरेंट स्कोप में समान retries वेरिएबल तक पहुंचने में सक्षम हैं।

retry के साथ समस्या

जबकि retry बहुत अच्छा है, इसकी कुछ सीमाएं हैं। मुख्य यह है कि पूरा begin ब्लॉक फिर से चलाया जाता है। लेकिन कभी-कभी यह आदर्श नहीं होता।

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

SocialMedia.post_to_all("Zomg! I just ate the biggest hamburger") # ...posts to Twitter API # ...posts to Facebook API # ...etc 

यदि API में से कोई एक प्रतिक्रिया देने में विफल रहता है, तो जेम एक SocialMedia::TimeoutError उठाता है और रोक देता है। अगर हम इस एक्सेप्शन को पकड़कर रीट्राई करते हैं, तो हम डुप्लिकेट पोस्ट के साथ समाप्त होंगे क्योंकि रीट्राई शुरुआत से शुरू होगा।

begin SocialMedia.post_to_all("Zomg! I just ate the biggest hamburger") rescue SocialMedia::TimeoutError retry end # ...posts to Twitter API # facebook error # ...posts to Twitter API # facebook error # ...posts to Twitter API # and so on 

क्या यह अच्छा नहीं होगा अगर हम जेम को बता सकें "बस फेसबुक को छोड़ दो, और API की सूची में पोस्ट करना जारी रखो।"

सौभाग्य से हमारे लिए, रूबी हमें ठीक ऐसा करने की अनुमति देता है।

नोट: बेशक इस समस्या का वास्तविक समाधान सोशल मीडिया लाइब्रेरी को पुनर्गठित करना है। लेकिन यह उन तकनीकों के लिए एकमात्र उपयोग-मामला नहीं है जो मैं आपको दिखाने जा रहा हूँ।

कंटिन्यूएशन से रेस्क्यू

कंटिन्यूएशन लोगों को डराते हैं। लेकिन यह सिर्फ इसलिए है क्योंकि उनका उपयोग अक्सर नहीं किया जाता और वे थोड़े अजीब दिखते हैं। लेकिन एक बार जब आप मूल बातें समझ लेते हैं तो वे वास्तव में काफी सरल होते हैं।

एक कंटिन्यूएशन आपके कोड में "सेव पॉइंट" की तरह है, बिल्कुल वीडियो गेम की तरह। आप जाकर अन्य काम कर सकते हैं, फिर सेव पॉइंट पर वापस कूद सकते हैं और सब कुछ वैसा ही होगा जैसा आपने छोड़ा था।

...ठीक है, तो यह एक आदर्श सादृश्य नहीं है, लेकिन यह कुछ हद तक काम करता है। आइए कुछ कोड देखें:

require "continuation" counter = 0 continuation = callcc { |c| c } # define our savepoint puts(counter += 1) continuation.call(continuation) if counter < 5 # jump back to our savepoint 

आपने कुछ अजीब चीजें देखी होंगी। आइए उनके माध्यम से चलते हैं:

  • हम कंटिन्यूएशन ऑब्जेक्ट बनाने के लिए callcc मेथड का उपयोग करते हैं। इसके लिए कोई साफ OO सिंटैक्स नहीं है।

  • पहली बार continuation वेरिएबल को असाइन किया जाता है, यह callcc के ब्लॉक के रिटर्न मान पर सेट होता है। इसलिए ब्लॉक का होना आवश्यक है।

  • हर बार जब हम सेव पॉइंट पर वापस कूदते हैं, तो continuation वेरिएबल को वह आर्गुमेंट असाइन किया जाता है जो हम call मेथड को पास करते हैं। इसलिए हम अजीब दिखने वाले continuation.call(continuation) सिंटैक्स का उपयोग करते हैं।

एक्सेप्शन में कंटिन्यूएशन जोड़ना

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

begin raise "the roof" puts "The exception was ignored" rescue => e e.skip end # ...outputs "The exception was ignored" 

इसे करने के लिए मुझे कुछ पाप करने होंगे। Exception सिर्फ एक क्लास है। इसका मतलब है कि मैं इसमें skip मेथड जोड़ने के लिए मंकीपैच कर सकता हूँ।

class Exception attr_accessor :continuation def skip continuation.call end end 

अब हमें हर एक्सेप्शन के लिए continuation एट्रिब्यूट सेट करने की आवश्यकता है। पता चला है कि raise सिर्फ एक मेथड है, जिसे हम ओवरराइड कर सकते हैं।

BTW, नीचे दिया गया कोड Advi के उत्कृष्ट स्लाइड डेक Things You Didn't know about Exceptions से लगभग शब्दशः लिया गया है। मैं बस इसके कार्यान्वयन का इससे बेहतर तरीका नहीं सोच सका:

require 'continuation' module StoreContinuationOnRaise def raise(*args) callcc do |continuation| begin super rescue Exception => e e.continuation = continuation super(e) end end end end class Object include StoreContinuationOnRaise end 

अब मैं किसी भी एक्सेप्शन के लिए skip मेथड को कॉल कर सकता हूँ और यह ऐसा होगा जैसे एक्सेप्शन कभी हुआ ही नहीं।


  1. रूबी में एनवायरनमेंट वेरिएबल्स मास्टर करें: एक व्यावहारिक मार्गदर्शिका रूबी में एनवायरनमेंट वेरिएबल्स मास्टर करें: एक व्यावहारिक मार्गदर्शिका

    एक एनवायरनमेंट वेरिएबल एक कुंजी/मान जोड़ी है, यह इस तरह दिखती है: KEY=VALUE हम इन वेरिएबल्स का उपयोग अपने कंप्यूटर में सभी प्रोग्राम्स के बीच कॉन्फ़िगरेशन विकल्प साझा करने के लिए करते हैं। यही कारण है कि यह सीखना महत्वपूर्ण है कि वे कैसे काम करते हैं और ENV विशेष वेरिएबल का उपयोग करके अपने रूबी प्

  1. रूबी मैट्रिक्स को समझना: परिभाषा, अनुप्रयोग और उन्हें कैसे बनाएं रूबी मैट्रिक्स को समझना: परिभाषा, अनुप्रयोग और उन्हें कैसे बनाएं

    मैट्रिक्स एक 2D (2-डायमेंशनल) ऐरे है जिसका उपयोग स्प्रेडशीट जैसे डेटा को स्टोर और काम करने के लिए किया जा सकता है। इनका उपयोग किया जा सकता है: टेबल गेम में बोर्ड को दर्शाना (शतरंज, चेकर्स, आदि) आंकड़े और डेटा विश्लेषण प्लॉट्स और ग्राफ़ उत्पन्न करना क्योंकि यह एक शक्तिशाली डेटा संरचना है इसलिए इसका

  1. रूबी स्ट्रक्ट्स और OpenStruct में महारत: कुशल वैल्यू ऑब्जेक्ट्स रूबी स्ट्रक्ट्स और OpenStruct में महारत: कुशल वैल्यू ऑब्जेक्ट्स

    रूबी में स्ट्रक्ट क्या है? एक स्ट्रक्ट एक बिल्ट-इन रूबी क्लास है, इसका उपयोग वैल्यू ऑब्जेक्ट्स उत्पन्न करने वाली नई क्लासेस बनाने के लिए किया जाता है। एक वैल्यू ऑब्जेक्ट संबंधित विशेषताओं को एक साथ संग्रहीत करने के लिए उपयोग किया जाता है। यहां एक उदाहरण है: दो निर्देशांकों (x और y) के साथ एक Point।