2011-06-03 13 views
9

इस begin-बचाव-सुनिश्चित ब्लॉक पर विचार करें:रूबी 'सुनिश्चित' नहीं है जब मैं 'बचाव' में 'पुन: प्रयास'

attempts=0 
begin 
    make_service_call() 
rescue Exception 
    retry unless attempts>2 
    exit -1 
ensure 
    attemps += 1 
end 

आपको लगता है कि कोड चलाते हैं के रूप में यह है, यह एक अपवाद है क्योंकि वहाँ को जन्म देती है 'make_service_call()' नामक कोई फ़ंक्शन नहीं है। तो, यह retries। लेकिन यह अनंत लूप में फंस जाएगा क्योंकि नियंत्रण 'पुनः प्रयास' के कारण कभी भी 'सुनिश्चित' नहीं होता है। ब्लॉक के हिस्से को 'सुनिश्चित' नहीं करना चाहिए, यह सुनिश्चित करना चाहिए कि उसमें कोड निष्पादित हो जाए, इससे कोई फर्क नहीं पड़ता कि 'शुरूआत' या 'बचाव' में क्या होता है?

बेशक मैं 'शुरुआत' में गिनती बढ़ा सकता हूं - यह बात नहीं है। मैं सिर्फ कुछ स्पष्टता प्राप्त करने के लिए 'सुनिश्चित' के बारे में सवाल पूछ रहा हूं।

उत्तर

17

ensure अनुभाग जब (किसी भी तरह से) begin बयान लेकिन जब आप retry, तुम बस के चारों ओर बयान के अंदर जा रहे हैं तो खंड सुनिश्चित निष्पादित नहीं किया जाएगा छोड़ने निष्पादित किया जाता है।

क्या हो रहा है की एक बेहतर विचार प्राप्त करने के लिए अपने उदाहरण के इस संस्करण का प्रयास करें:

attempts = 0 
begin 
    make_service_call() 
rescue Exception 
    attempts += 1 
    retry unless attempts > 2 
    exit -1 
ensure 
    puts "ensure! #{attempts}" 
end 
2

ensure कोड एक बार मार डाला जाता है, बस कोड ब्लॉक रास्ते से पहले और यह उस समय कहा जा होगा।

लेकिन क्योंकि unless attempts>2 हालत, और तथ्य यह है कि ensure केवल बुलाया जाएगा की "बस से पहले कोड बाहर निकलता है" (उदा exit -1 के कारण) attempts += 1 निष्पादित नहीं किया जाएगा, और इसलिए वहाँ एक अनंत लूप है।

ensure C++ __finally की तरह है: आप अपवाद catch सकता है और उसके बाद का उपयोग एक goto: लेकिन जब तक समारोह वास्तव में के बारे में बाहर निकलने के लिए है finally बुलाया नहीं किया जाएगा।

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