2010-12-07 8 views
12

रूबी में एक साधारण कमांड लाइन उपकरण लिखना मुझे कमांड लाइन तर्कों में त्रुटियों पर सार्थक संदेशों की रिपोर्ट करने की आवश्यकता है, या उस मामले में प्रोग्राम में अन्य त्रुटि स्थितियों के लिए। (इनपुट फ़ाइल नहीं मिली, इनपुट आदि का अवैध प्रारूप)सर्वोत्तम अभ्यास: रूबी में त्रुटि की स्थिति के लिए आपूर्ति की गई प्रणाली या कस्टम अपवादों का उपयोग करना?

अभी के लिए मैं तर्क सूची में त्रुटियों का पता लगाने के दौरान केवल एक समझदार वर्णन के साथ ArgumentError उठाता हूं। क्या यह अच्छा अभ्यास है, या क्या मैं इस दृष्टिकोण के साथ प्रोग्रामिंग त्रुटियों को छिपाने का जोखिम उठाता हूं? दूसरे शब्दों में, क्या सिस्टम अनुप्रयोग उपयोग के लिए रूबी में परिभाषित अपवाद हैं, या क्या हमें हमेशा गैर-सिस्टम त्रुटियों की रिपोर्ट करने के लिए अपना अपवाद बनाना चाहिए?

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

+1

संबंधित प्रश्न: [रूबी में सही अपवाद उपclass का उपयोग करना] (http://stackoverflow.com/questions/699372/using-the-right-exception-subclass-in-ruby) –

+0

एंड्रयू, धन्यवाद, मुझे वह याद आया । – harald

उत्तर

15

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

module MyApp 
    class Error < StandardError; end 
    class ArgumentError < Error; end 
end 

और उपयोगकर्ता द्वारा खराब तर्क प्रदान करते समय MyApp :: ArgumentError बढ़ाएं। इस तरह यह आपके कोड में एक तर्क त्रुटि से भिन्न होता है। और आप MyApp :: त्रुटि के साथ उच्च स्तर पर अपने ऐप से किसी भी अपरिपक्व अपवाद को बचा सकते हैं।

आपको Thor भी देखना चाहिए। यह आपके लिए उपयोगकर्ता तर्क सामग्री के अधिकांश संभाल सकता है। आप एक अच्छी क्ली उपयोग उदाहरण के लिए Bundler देख सकते हैं।

28

रूबी 1.9 अपवाद पदानुक्रम इस प्रकार है:

Exception 
+- NoMemoryError 
+- ScriptError 
| +- LoadError 
| +- NotImplementedError 
| +- SyntaxError 
+- SignalException 
| +- Interrupt 
+- StandardError 
| +- ArgumentError 
| +- IOError 
| | +- EOFError 
| +- IndexError 
| +- LocalJumpError 
| +- NameError 
| | +- NoMethodError 
| +- RangeError 
| | +- FloatDomainError 
| +- RegexpError 
| +- RuntimeError 
| +- SecurityError 
| +- SystemCallError 
| +- SystemStackError 
| +- ThreadError 
| +- TypeError 
| +- ZeroDivisionError 
+- SystemExit 
+- fatal 

रूबी 2 अपवाद पदानुक्रम है: आप के रूप में

Exception 
+- NoMemoryError 
+- ScriptError 
| +- LoadError 
| +- NotImplementedError 
| +- SyntaxError 
+- SecurityError 
+- SignalException 
| +- Interrupt 
+- StandardError # default for rescue 
| +- ArgumentError 
| | +- UncaughtThrowError 
| +- EncodingError 
| +- FiberError 
| +- IOError 
| | +- EOFError 
| +- IndexError 
| | +- KeyError 
| | +- StopIteration 
| +- LocalJumpError 
| +- NameError 
| | +- NoMethodError 
| +- RangeError 
| | +- FloatDomainError 
| +- RegexpError 
| +- RuntimeError # default for raise 
| +- SystemCallError 
| | +- Errno::* 
| +- ThreadError 
| +- TypeError 
| +- ZeroDivisionError 
+- SystemExit 
+- SystemStackError 
+- fatal # impossible to rescue 

आप इनमें से किसी एक का उपयोग कर सकते हैं, या अपना खुद का बना। अपना खुद का निर्माण करते समय, कुछ चीजें ध्यान देने योग्य हैं। एक के लिए, rescue डिफ़ॉल्ट रूप से केवल StandardError और इसके वंशजों को बचाता है। मुझे यह सब बड़ी कठिनाईयों का सामना करने के बाद मिला है। यह सुनिश्चित करना सबसे अच्छा है कि आपकी कस्टम त्रुटियां StandardError से प्राप्त हों। (वैसे, किसी भी अपवाद को बचाने के लिए, स्पष्ट रूप से rescue Exception का उपयोग करें।)

आप एक अपवाद वर्ग गुण, कस्टम कंस्ट्रक्टर्स, आदि के साथ पूरा बना सकते हैं, लेकिन मानक अभ्यास सिर्फ सरल परिभाषाओं बनाने के लिए है:

class ProcessingError < RuntimeError; end 

आप अलग-अलग त्रुटि संदेशों के साथ विशिष्ट त्रुटियों को अलग कर सकते हैं, या त्रुटियों का पदानुक्रम बना सकते हैं। विस्तृत अपवाद पदानुक्रम आम तौर पर नहीं किया जाता है, या कम से कम मैंने इसका एक उदाहरण नहीं देखा है (और मैं पुस्तकालयों के स्रोत को पढ़ता हूं)। मैंने जो देखा है वह आपकी त्रुटियों को नाम देने के लिए मॉड्यूल का उपयोग है, जो मुझे लगता है कि एक अच्छा विचार है।

module MyLibrary 
    class Error < StandardError; end 
    class ConnectionError < Error; end 
end 

फिर अपने अपवाद रूप MyLibrary::ConnectionError का होगा और आप rescue MyLibrary::Error कर सकते हैं विशेष रूप से अपने पुस्तकालय से त्रुटियों को बचाने और उन सब को पकड़ने के लिए।

नोट: एक वैकल्पिक वाक्यविन्यास MyError = Class.new(RuntimeError) स्टीव क्लाबनिक के ब्लॉग पोस्ट के संदर्भ को देखें।

संदर्भ:

एक शानदार पढ़ा: Exceptional Ruby Avdi ग्रिम

+0

धन्यवाद, मुझे अपवाद पदानुक्रम के बारे में पता है, लेकिन मैं इसके सही उपयोग के बारे में अनिश्चित हूं। बकलॉग संदर्भ बहुत अंतर्दृष्टिपूर्ण था, यद्यपि! मैंने उम्मीदों को थोड़ा सा स्पष्ट रूप से मेरी चिंताओं को थोड़ा स्पष्ट करने के लिए अद्यतन किया है। – harald

+1

मुझे यकीन नहीं है कि एक ट्रू वे है या नहीं; क्योंकि यह पायथन नहीं है :)। मैंने कोड को अंतर्निहित अपवादों का उपयोग किया है, और मैंने कोड का उपयोग कस्टम वाले लोगों को देखा है। जैसा कि मैंने निहित किया है, मेरी प्राथमिकता मानक एरर के मॉड्यूल-स्कोप्ड वंशजों का उपयोग करना है। –

+3

'वर्ग MyError

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

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