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

रूबी में अपवाद होने पर पुन:प्रयास कैसे करें?

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

पेश है 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

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

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

SocialMedia.post_to_all("Zomg! I just ate the biggest hamburger")

# ...posts to Twitter API
# ...posts to Facebook API
# ...etc

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

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

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

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

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

बचाव के लिए निरंतरता

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

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

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

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

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

  • कंटिन्यूएशन ऑब्जेक्ट बनाने के लिए हम कॉलसीसी विधि का उपयोग करते हैं। इसके लिए कोई साफ 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 . जोड़ने के लिए इसे moonekypatch कर सकता हूं विधि।

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

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

BTW, नीचे दिए गए कोड को अदवी के उत्कृष्ट स्लाइड डेक से लगभग शब्दशः लिया गया है जो आप अपवादों के बारे में नहीं जानते थे। मैं इसे लागू करने का इससे बेहतर तरीका नहीं सोच सकता था:

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. एक मैट्रिक्स क्या है और रूबी में इसका उपयोग कैसे करें?

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

  1. रूबी में स्ट्रक्चर और ओपनस्ट्रक्चर का उपयोग कैसे करें?

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