बुराई पर जोर है? [बन्द है]


199

Goभाषा रचनाकारों बारे में :

जाओ दावे प्रदान नहीं करता है। वे निर्विवाद रूप से सुविधाजनक हैं, लेकिन हमारा अनुभव रहा है कि उचित त्रुटि से निपटने और रिपोर्टिंग के बारे में सोचने से बचने के लिए प्रोग्रामर उन्हें एक बैसाखी के रूप में उपयोग करते हैं। उचित त्रुटि हैंडलिंग का मतलब है कि सर्वर दुर्घटनाग्रस्त होने के बजाय गैर-घातक त्रुटियों के बाद ऑपरेशन जारी रखते हैं। उचित त्रुटि रिपोर्टिंग का मतलब है कि त्रुटियाँ प्रत्यक्ष और बिंदु तक हैं, प्रोग्रामर को एक बड़े क्रैश ट्रेस की व्याख्या करने से बचाती है। सटीक त्रुटियां विशेष रूप से महत्वपूर्ण हैं जब प्रोग्रामर त्रुटियों को देखकर कोड से परिचित नहीं है।

इस बारे में आपकी क्या राय है?


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

@allyourcode यदि आप इसका उल्लेख कर रहे हैं reflect.DeepEqual, तो आपको निश्चित रूप से इसकी आवश्यकता नहीं है। यह सुविधाजनक है, लेकिन प्रदर्शन की लागत पर (इकाई परीक्षण एक अच्छा उपयोग मामला है)। अन्यथा, आप बहुत अधिक परेशानी के बिना अपने "संग्रह" के लिए जो भी समानता की जाँच करें, उसे लागू कर सकते हैं।
इगोर डबिन्सकी

1
नहीं, यह मैं नहीं कह रहा हूं। प्रतिबिंब के बिना स्लाइस 1 == स्लाइस 2 जैसी कोई चीज नहीं है। अन्य सभी भाषाएँ इस सुपर बेसिक ऑपरेशन के बराबर हैं। एकमात्र कारण गो न होना पूर्वाग्रह है।
अलायूरोडेकोड

आप दो स्लाइस की तुलना forगो (केवल सी की तरह) में लूप का उपयोग किए बिना कर सकते हैं । यह होता है , वास्तव में सामान्य टुकड़ा संचालन के लिए अच्छा है, हालांकि तुलना जटिल हो जाता है जब संकेत और structs शामिल हैं।
kbolino

जवाबों:


321

नहीं, assertजब तक आप इसे इच्छित रूप में उपयोग करते हैं, तब तक कुछ भी गलत नहीं है ।

यह है, यह उन मामलों को पकड़ने के लिए माना जाता है जो "नहीं हो सकते", डिबगिंग के दौरान, सामान्य त्रुटि हैंडलिंग के विपरीत।

  • जोर: कार्यक्रम के तर्क में ही विफलता।
  • त्रुटि हैंडलिंग: प्रोग्राम में बग के कारण गलत इनपुट या सिस्टम स्थिति नहीं है।

109

नहीं है, न तो gotoहै और न ही assertबुराई कर रहे हैं। लेकिन दोनों का दुरुपयोग किया जा सकता है।

जोर स्वच्छता जांच के लिए है। चीजें जो प्रोग्राम को मारना चाहिए यदि वे सही नहीं हैं। सत्यापन के लिए नहीं या त्रुटि से निपटने के लिए प्रतिस्थापन के रूप में।


कैसे gotoबुद्धिमानी से उपयोग करने के लिए ?
ar2015

1
@ ar2015 एक बेतुके रूप से विरोधाभासी पैटर्न का पता लगाएं, जिसे कुछ लोग gotoविशुद्ध रूप से धार्मिक कारणों से बचने की सलाह देते हैं , तो बस gotoआप जो कर रहे हैं उसे रोकने के बजाय उपयोग करें । दूसरे शब्दों में: यदि आप साबित कर सकते हैं कि आपको वास्तव में जरूरत है goto, और एकमात्र विकल्प व्यर्थ मचान का एक भार अधिनियमित करना है जो अंततः वही काम करता है, लेकिन गोटो पुलिस को बदले बिना ... तो बस उपयोग करें goto। बेशक, इसका एक पूर्व शर्त है "यदि आप साबित कर सकते हैं कि आपको वास्तव में ज़रूरत है goto"। अक्सर, लोग नहीं करते हैं। इसका मतलब यह नहीं है कि यह एक बुरी बात है।
अंडरस्कोर_ड

2
gotoकोड क्लीनअप के लिए लिनक्स कर्नेल में उपयोग किया जाता है
malat

61

उस तर्क से, विराम बिंदु भी बुरे हैं।

आवेषण का उपयोग डिबगिंग सहायता के रूप में किया जाना चाहिए, और कुछ नहीं। "बुराई" तब होती है जब आप त्रुटि से निपटने के बजाय उनका उपयोग करने का प्रयास करते हैं ।

प्रोग्रामर आपकी मदद करने के लिए हैं, प्रोग्रामर, उन समस्याओं का पता लगाता है और उन्हें ठीक करता है जो मौजूद नहीं होनी चाहिए और यह सत्यापित करना चाहिए कि आपकी धारणा सही है।

उनके पास त्रुटि से निपटने के लिए कुछ भी नहीं है, लेकिन दुर्भाग्य से, कुछ प्रोग्रामर उन्हें इस तरह से दुरुपयोग करते हैं, और फिर उन्हें "बुराई" घोषित करते हैं।


40

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

क्योंकि मैं बहुत कम समय कोडिंग / डिबगिंग कार्यक्रमों में खर्च करता हूं।

मैंने यह भी देखा है कि मुखर मुझे कई चीजों के बारे में सोचने में मदद करते हैं जो मेरे कार्यक्रमों को तोड़ सकती हैं।


31

एक अतिरिक्त जानकारी के रूप में, एक अंतर्निहित फ़ंक्शन प्रदान करता है panic। के स्थान पर इसका उपयोग किया जा सकता है assert। उदाहरण के लिए

if x < 0 {
    panic("x is less than 0");
}

panicस्टैक ट्रेस को प्रिंट करेगा, इसलिए किसी तरह इसका उद्देश्य है assert


30

कार्यक्रम में बग का पता लगाने के लिए उनका उपयोग किया जाना चाहिए। बुरा उपयोगकर्ता इनपुट नहीं।

यदि सही तरीके से उपयोग किया जाता है, तो वे बुराई नहीं हैं।


13

यह बहुत ऊपर आता है, और मुझे लगता है कि एक समस्या है जो दावे के बचाव को भ्रामक बनाती है, वे अक्सर तर्क जांच पर आधारित होती हैं। इसलिए इस बात पर विचार करें कि आप कब उपयोग कर सकते हैं:

build-sorted-list-from-user-input(input)

    throw-exception-if-bad-input(input)

    ...

    //build list using algorithm that you expect to give a sorted list

    ...

    assert(is-sorted(list))

end

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

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


8

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

व्यक्तिगत रूप से, मैं अभिकथन का उपयोग करना पसंद करता हूं क्योंकि वे मान्यताओं को दस्तावेज करते हैं जो मैंने अपना कोड लिखते समय बनाया हो सकता है। यदि कोड को बनाए रखते हुए इन मान्यताओं को तोड़ा जाता है, तो समस्या का परीक्षण के दौरान पता लगाया जा सकता है। हालाँकि, मैं एक प्रोडक्शन बिल्ड (यानी, #ifdefs का उपयोग करके) करते समय अपने कोड से प्रत्येक अभिकथन को अलग करने की बात करता हूँ। उत्पादन के निर्माण में जोर देकर, मैं किसी को भी एक बैसाखी के रूप में दुरुपयोग करने के जोखिम को समाप्त करता हूं।

अभिकथन के साथ एक और समस्या भी है। दावे केवल रन-टाइम पर जांचे जाते हैं। लेकिन अक्सर ऐसा होता है कि आप जो चेक करना चाहते हैं, वह संकलन-समय पर किया जा सकता है। संकलन के समय किसी मुद्दे का पता लगाना बेहतर होता है। C ++ प्रोग्रामर के लिए, बढ़ावा BOOST_STATIC_ASSERT प्रदान करता है जो आपको ऐसा करने की अनुमति देता है। सी प्रोग्रामर के लिए, यह लेख ( लिंक पाठ ) एक ऐसी तकनीक का वर्णन करता है जिसका उपयोग संकलन समय पर जोर देने के लिए किया जा सकता है।

सारांश में, मेरे द्वारा अनुसरण किए जाने वाले अंगूठे का नियम है: किसी निर्माण बिल्ड में अभिक्रियाओं का उपयोग न करें और यदि संभव हो तो केवल उन चीज़ों के लिए अभिकथनों का उपयोग करें, जिन्हें संकलन-समय पर सत्यापित नहीं किया जा सकता है (अर्थात, रन-टाइम पर जाँच की जानी चाहिए)।


5

मैं मानता हूं कि उचित त्रुटि रिपोर्टिंग पर विचार न करते हुए मुखरता का उपयोग किया गया है। हालांकि, यह दूर नहीं ले जाता है कि जब वे सही ढंग से उपयोग किए जाते हैं तो वे बहुत सहायक होते हैं।

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


5

मैं उस कोड से बचना पसंद करता हूं जो डिबग और रिलीज़ में अलग-अलग चीजें करता है।

डिबगर में किसी शर्त पर ब्रेक लगाना और सभी फ़ाइल / लाइन की जानकारी होना उपयोगी है, हालांकि सटीक अभिव्यक्ति और सटीक मूल्य भी।

यह दावा करते हुए कि "डिबग में केवल स्थिति का मूल्यांकन करेगा" एक प्रदर्शन अनुकूलन हो सकता है, और इस तरह, केवल 0.0001% कार्यक्रमों में उपयोगी है - जहां लोग जानते हैं कि वे क्या कर रहे हैं। अन्य सभी मामलों में यह हानिकारक है, क्योंकि अभिव्यक्ति वास्तव में कार्यक्रम की स्थिति बदल सकती है:

assert(2 == ShroedingersCat.GetNumEars()); इस कार्यक्रम को डिबग और रिलीज़ में अलग-अलग काम करेगा।

हमने मुखर मैक्रो का एक सेट विकसित किया है जो एक अपवाद को फेंक देगा, और इसे डिबग और रिलीज़ संस्करण दोनों में करेगा। उदाहरण के लिए, THROW_UNLESS_EQ(a, 20);क्या () संदेश फ़ाइल, रेखा और वास्तविक मान दोनों के साथ अपवाद को फेंक देगा , और इसी तरह। केवल एक मैक्रो के पास इसके लिए शक्ति होगी। डिबगर को विशिष्ट अपवाद प्रकार के 'थ्रो' पर तोड़ने के लिए कॉन्फ़िगर किया जा सकता है।


4
तर्कों में उपयोग किए गए 90% आँकड़े झूठे हैं।
जोहो पोर्टेला

5

मैं जोर से नापसंद करता हूं। मैं यह कहते हुए नहीं जाऊंगा कि वे हालांकि दुष्ट हैं।

मूल रूप से एक मुखर एक अनियंत्रित अपवाद के रूप में एक ही काम करेगा, एकमात्र अपवाद यह है कि अंतिम उत्पाद के लिए मुखर (सामान्य रूप से) नहीं रखा जाना चाहिए।

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

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


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


3

मैंने हाल ही में अपने कोड में कुछ जोड़ दिए हैं, और यह है कि मैं यह कैसे कर रहा हूं:

मैं मानसिक रूप से अपने कोड को सीमा कोड और आंतरिक कोड में विभाजित करता हूं। सीमा कोड वह कोड है जो उपयोगकर्ता इनपुट को संभालता है, फाइलों को पढ़ता है, और नेटवर्क से डेटा प्राप्त करता है। इस कोड में, मैं एक लूप में इनपुट का अनुरोध करता हूं जो केवल तभी बाहर निकलता है जब इनपुट वैध होता है (इंटरैक्टिव उपयोगकर्ता इनपुट के मामले में), या अपरिवर्तनीय फ़ाइल / नेटवर्क भ्रष्ट डेटा के मामले में अपवाद फेंकते हैं।

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

void Class::f (int value) {
    assert (value < end);
    member = value;
}

और एक फ़ंक्शन जिसे नेटवर्क से इनपुट मिलता है वह इस प्रकार पढ़ सकता है:

void Class::g (InMessage & msg) {
    int const value = msg.read_int();
    if (value >= end)
        throw InvalidServerData();
    f (value);
}

इससे मुझे चैक की दो परतें मिलती हैं। कुछ भी जहां डेटा रन-टाइम पर निर्धारित किया जाता है, हमेशा एक अपवाद या तत्काल त्रुटि से निपटने के लिए मिलता है। हालाँकि, स्टेटमेंट के Class::fसाथ उस अतिरिक्त जाँच का assertमतलब है कि अगर कुछ आंतरिक कोड कभी कॉल करता है Class::f, तो भी मेरे पास एक चैक है। मेरा आंतरिक कोड एक वैध तर्क पारित नहीं कर सकता है (क्योंकि मैंने valueकुछ जटिल श्रृंखलाओं से गणना की हो सकती है ), इसलिए मुझे सेटिंग फ़ंक्शन में यह दावा करना पसंद है कि दस्तावेज़ को कॉल करने के बावजूद, जो फ़ंक्शन को कॉल valueनहीं कर रहा है या उससे अधिक नहीं होना चाहिए के बराबर है end

ऐसा लगता है कि मैं कुछ स्थानों पर पढ़ रहा हूं, जो कि एक अच्छी तरह से काम कर रहे कार्यक्रम में उल्लंघन करने के लिए असंभव होना चाहिए, जबकि अपवाद असाधारण और गलत मामलों के लिए होना चाहिए जो अभी भी संभव हैं। क्योंकि सिद्धांत रूप में, मैं सभी इनपुट को मान्य कर रहा हूं, इसलिए मेरे दावे को ट्रिगर करना संभव नहीं होना चाहिए। अगर ऐसा है, तो मेरा कार्यक्रम गलत है।


2

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

उदाहरण के लिए, एक 3 पार्टी मॉड्यूल (या वास्तव में कोई भी मॉड्यूल) को कॉलिंग प्रोग्राम से लगभग कभी भी बाहर नहीं निकलना चाहिए। यह कॉलिंग प्रोग्रामर को उस पल में क्या जोखिम उठाना चाहिए, इस पर कोई नियंत्रण नहीं देता है। कई मामलों में, डेटा इतना महत्वपूर्ण है कि दूषित डेटा को सहेजना भी उस डेटा को खोने से बेहतर है। जोर आपको डेटा खोने के लिए मजबूर कर सकता है।

मुखर करने के लिए कुछ विकल्प:

  • डीबगर का उपयोग करना,
  • कंसोल / डेटाबेस / अन्य लॉगिंग
  • अपवाद
  • अन्य प्रकार की त्रुटि से निपटने

कुछ संदर्भ:

यहां तक ​​कि लोग जो मुखर होने की वकालत करते हैं उन्हें लगता है कि उन्हें केवल विकास में उपयोग किया जाना चाहिए कि उत्पादन में:

यह व्यक्ति कहता है कि मॉड्यूल का उपयोग तब किया जाना चाहिए जब मॉड्यूल में संभावित रूप से दूषित डेटा होता है जो एक अपवाद के बाद बनी रहती है: http://www.advogato.org/article/949.html । यह निश्चित रूप से एक उचित बिंदु है, हालांकि, एक बाहरी मॉड्यूल को कभी भी यह नहीं बताना चाहिए कि कॉलिंग प्रोग्राम के लिए कितना महत्वपूर्ण भ्रष्ट डेटा है ("उन्हें" के लिए बाहर निकलने से)। इसे संभालने का उचित तरीका एक अपवाद को फेंकने से है जो यह स्पष्ट करता है कि कार्यक्रम अब असंगत स्थिति में हो सकता है। और चूंकि अच्छे कार्यक्रमों में ज्यादातर मॉड्यूल शामिल होते हैं (मुख्य निष्पादन योग्य में थोड़ा गोंद कोड के साथ), मुखर लगभग हमेशा गलत काम करते हैं।


1

assert बहुत उपयोगी है और जब आप अनपेक्षित त्रुटियों को समस्या के पहले लक्षणों पर रोकते हैं, तो आप बहुत सारे बैकग्राउंड को बचा सकते हैं।

दूसरी ओर, इसका दुरुपयोग करना बहुत आसान है assert

int quotient(int a, int b){
    assert(b != 0);
    return a / b;
}

उचित, सही संस्करण कुछ इस तरह होगा:

bool quotient(int a, int b, int &result){
    if(b == 0)
        return false;

    result = a / b;
    return true;
}

इसलिए ... लंबे समय में ... बड़ी तस्वीर में ... मुझे सहमत होना चाहिए कि assertदुरुपयोग किया जा सकता है। मुझे हर व़क्त यह करना है।


1

assert त्रुटि हैंडलिंग के लिए दुर्व्यवहार किया जा रहा है क्योंकि यह कम टाइपिंग है।

इसलिए भाषा डिजाइनरों के रूप में, उन्हें यह देखना चाहिए कि उचित त्रुटि से निपटने को और भी कम टाइपिंग के साथ किया जा सकता है। आपके अपवाद तंत्र को छोड़कर क्रिया को छोड़कर, समाधान नहीं है। ओह रुको, गो के पास अपवाद भी नहीं हैं। बहुत बुरा :)


1
बहुत बुरा नहीं है :) अपवाद या नहीं, दावे या नहीं, गो प्रशंसक अभी भी इस बारे में बात कर रहे हैं कि कोड कितने कम हैं।
मोशे रेवह

1

मुझे लगा कि जब मैंने देखा तो लेखक को सिर में लात मारी।

मैं कोड में सभी समय का उपयोग करता हूं और अंततः अधिक कोड लिखने पर उन सभी को बदल देता हूं। मैं उनका उपयोग तब करता हूं जब मैंने आवश्यक तर्क नहीं लिखा होता है और जब मैं एक अपवाद लिखने के बजाय कोड में भाग लेता हूं, तो इसे सतर्क कर दिया जाना चाहिए जो परियोजना के पूरा होने के करीब पहुंच जाएगा।

अपवाद भी उत्पादन कोड के साथ अधिक आसानी से मिश्रण करते हैं जो मुझे नापसंद है। एक मुखर की तुलना में नोटिस करना आसान हैthrow new Exception("Some generic msg or 'pretend i am an assert'");


1

मुखर बचाव करने वाले इन उत्तरों के साथ मेरी समस्या यह है कि कोई भी स्पष्ट रूप से निर्दिष्ट नहीं करता है कि यह एक नियमित घातक त्रुटि से अलग क्या है , और एक मुखर अपवाद का एक उपसमूह क्यों नहीं हो सकता है । अब, इस के साथ, अगर अपवाद कभी नहीं पकड़ा गया तो क्या होगा? क्या यह नामकरण द्वारा एक जोर देता है? और, आप कभी भी भाषा में प्रतिबंध क्यों लगाना चाहेंगे कि एक अपवाद उठाया जा सकता है कि / कुछ नहीं / संभाल सकता है?


अगर आप मेरे जवाब को देखेंगे। मेरा उपयोग 'अपवादों' (जोर) को अलग करने के लिए है जिसे मैं डिबगिंग बनाम अपवादों के लिए इस्तेमाल से छुटकारा पाना चाहता हूं जो मैं रखता हूं। मैं उनसे क्यों छुटकारा पाना चाहूंगा? क्योंकि उनके बिना काम करना पूर्ण नहीं होगा। उदाहरण है अगर मैं 3 मामलों को संभालता हूं और 4 वें टूडू है। मैं कोड में उन्हें खोजने के लिए आसानी से खोज कर सकता हूं और इसके अधूरेपन को जान सकता हूं, फिर एक अपवाद का उपयोग कर सकता हूं जो गलती से पकड़ा जा सकता है (दूसरे प्रोग्रामर द्वारा) या यह बताने के लिए कि क्या मैं इसका अपवाद या तर्क जांचता हूं कि कोड में हल करना चाहिए।

मेरी नज़र में, यह एक खराब विचार है, "सीलबंद" कक्षाओं के समान स्तर पर और बस उसी कारण से। आप उन अपवादों को मान रहे हैं जिन्हें आप रखना चाहते हैं जो आपके कोड के उपयोग के लिए स्वीकार्य हैं जिन्हें आप अभी तक नहीं जानते हैं। सभी अपवाद समान चैनलों के माध्यम से जाते हैं, और यदि उपयोगकर्ता उन्हें नहीं पकड़ना चाहता है तो वह नहीं चुन सकता है। यदि वह करता है, तो उसके पास भी क्षमता होनी चाहिए। किसी भी तरह से, आप सिर्फ धारणा बना रहे हैं या अपने अभ्यास को एक अवधारणा की तरह आगे बढ़ा रहे हैं।
इवान कैरोल

मैंने तय किया कि उदाहरण परिदृश्य सबसे अच्छे हैं। एक साधारण एक है। int func (int i) {if (i> = 0) {कंसोल.राइट ("संख्या सकारात्मक है {0}", i); } और {मुखर (झूठा); // नकारात्मक करने के लिए आलसी करने के लिए ATM} वापसी i * 2; <- मैं इसे बिना जोर लगाए कैसे करूंगा और यह वास्तव में बेहतर है? और याद रखें, यह कोड रिलीज़ से पहले लागू किया जाएगा।

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

इस बिंदु पर, आप SHOULDNT कहते हैं कि उपयोगकर्ता क्या नहीं कर सकता है। एप्लिकेशन को त्रुटि संदेश के साथ समाप्त करना चाहिए और जो भी डिबगिंग कर रहा है, वह कुछ ऐसा याद रखेगा कि SHOULD BE DONE लेकिन isnt नहीं है। आप इसे संभालना नहीं चाहते। आप एक समाप्ति चाहते हैं और आपको याद दिलाया जाना चाहिए कि आपने उस मामले को नहीं संभाला है। और यह देखना बेहद आसान है कि आपको किन मामलों को छोड़ना है क्योंकि आपको कोड में खोज करने की आवश्यकता है। त्रुटि को हैंडल करना गलत होगा क्योंकि कोड उत्पादन के लिए तैयार होने के बाद इसे करने में सक्षम होना चाहिए। प्रोग्रामर को इसे पकड़ने और कुछ और करने की अनुमति देना गलत है।

1

हां, मुखर बुराई है।

अक्सर वे उन जगहों पर उपयोग किए जाते हैं जहां उचित त्रुटि हैंडलिंग का उपयोग किया जाना चाहिए। शुरू से ही उचित उत्पादन गुणवत्ता त्रुटि से निपटने की आदत डालें!

आमतौर पर वे इकाई परीक्षण लिखने के तरीके से प्राप्त करते हैं (जब तक कि आप एक कस्टम मुखर नहीं लिखते हैं जो आपके परीक्षण हार्नेस के साथ बातचीत करता है)। यह अक्सर होता है क्योंकि उनका उपयोग किया जाता है जहां उचित त्रुटि हैंडलिंग का उपयोग किया जाना चाहिए।

अधिकतर वे रिलीज़ बिल्ड से संकलित हो जाते हैं, जिसका अर्थ है कि जब आप वास्तव में रिलीज़ होने वाले कोड को चला रहे हों, तो उनका कोई भी "परीक्षण" उपलब्ध नहीं होता है; यह देखते हुए कि बहु-थ्रेडेड स्थितियों में सबसे खराब समस्याएं अक्सर केवल रिलीज कोड में दिखाई देती हैं यह खराब हो सकता है।

कभी-कभी वे अन्यथा टूटे हुए डिजाइनों के लिए एक बैसाखी होते हैं; यानी कोड का डिज़ाइन किसी उपयोगकर्ता को इसे इस तरह से कॉल करने की अनुमति देता है कि इसे कॉल न किया जाए और एस्टर इसे रोकता है। डिजाइन ठीक करें!

मैंने 2005 में अपने ब्लॉग पर इसके बारे में और अधिक यहाँ लिखा: http://www.lenholgate.com/blog/2005/09/assert-is-evin.html


0

आम तौर पर उल्टा इतना बुरा नहीं है। स्थायी त्रुटि जाँच और डीबगिंग के बीच एक अलगाव है। मुखर लोगों को लगता है कि सभी डिबगिंग स्थायी होनी चाहिए और बहुत अधिक उपयोग किए जाने पर बड़े पैमाने पर पठनीयता समस्याओं का कारण बनती है। स्थायी त्रुटि से निपटने के लिए बेहतर होना चाहिए जहां जरूरत है, और क्योंकि मुखर अपनी त्रुटियों का कारण बनता है यह एक बहुत ही संदिग्ध अभ्यास है।


5
मुखर एक समारोह के शीर्ष पर पूर्व स्थितियों की घोषणा करने के लिए अच्छा है, और यदि स्पष्ट रूप से लिखा गया है, तो फ़ंक्शन के प्रलेखन के हिस्से के रूप में कार्य करता है।
पीटर कॉर्ड्स

0

मैं कभी भी मुखर () का उपयोग नहीं करता, उदाहरण आमतौर पर ऐसा कुछ दिखाते हैं:

int* ptr = new int[10];
assert(ptr);

यह बुरा है, मैं ऐसा कभी नहीं करता, क्या होगा अगर मेरा खेल राक्षसों का एक समूह आवंटित कर रहा है? मुझे गेम को क्रैश क्यों करना चाहिए, इसके बजाय आपको त्रुटियों को इनायत से संभालना चाहिए, इसलिए कुछ ऐसा करें:

CMonster* ptrMonsters = new CMonster[10];
if(ptrMonsters == NULL) // or u could just write if(!ptrMonsters)
{
    // we failed allocating monsters. log the error e.g. "Failed spawning 10 monsters".
}
else
{
    // initialize monsters.
}

14
newकभी नहीं लौटता nullptr, यह फेंकता है।
डेविड स्टोन

ध्यान दें कि आप इसके लिए std :: nothrow का उपयोग कर सकते हैं ।
मार्कंड
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.