पसंदीदा (चतुर) रक्षात्मक प्रोग्रामिंग सबसे अच्छा अभ्यास [बंद]


148

यदि आपको रक्षात्मक कोडिंग के लिए अपनी पसंदीदा (चतुर) तकनीक का चयन करना है, तो वे क्या होंगे? यद्यपि मेरी वर्तमान भाषा जावा और ऑब्जेक्टिव-सी हैं (C ++ में पृष्ठभूमि के साथ), किसी भी भाषा में उत्तर देने के लिए स्वतंत्र महसूस करें। यहाँ जोर चालाक रक्षात्मक तकनीकों पर होगा जो कि हमारे यहां 70% + के अलावा अन्य लोग पहले से ही जानते हैं। इसलिए अब समय आ गया है कि आप अपने टोटकों की गहराई में खुदाई करें।

दूसरे शब्दों में इस निर्बाध उदाहरण के अलावा अन्य सोचने की कोशिश करें :

  • if(5 == x) इसके बजाय if(x == 5) : अनपेक्षित असाइनमेंट से बचने के लिए

यहाँ कुछ पेचीदा सर्वश्रेष्ठ रक्षात्मक प्रोग्रामिंग प्रथाओं के कुछ उदाहरण दिए गए हैं (भाषा-विशिष्ट उदाहरण जावा में हैं):

- अपने चरों को तब तक लॉक करें जब तक आपको पता न हो कि आपको उन्हें बदलना है

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

public void foo(final int arg) { /* Stuff Here */ }

- जब कुछ बुरा होता है, तो सबूत के निशान को पीछे छोड़ दें

जब आप एक अपवाद होते हैं तो आप कई चीजें कर सकते हैं: जाहिर है कि इसे लॉग इन करना और कुछ सफाई करना कुछ ही होगा। लेकिन आप साक्ष्य का एक निशान भी छोड़ सकते हैं (जैसे "UNABLE TO LOAD FILE" या 99999 जैसे वैरिएबल वैल्यूज़ सेट करना डिबगर में उपयोगी होगा, यदि आप अपवाद- catchवार को अतीत में उड़ा देते हैं तो)।

- जब यह स्थिरता की बात आती है: शैतान विवरण में है

आपके द्वारा उपयोग किए जा रहे अन्य पुस्तकालयों के अनुरूप हो। उदाहरण के लिए, जावा में, यदि आप एक ऐसी विधि का निर्माण कर रहे हैं, जो मानों की एक सीमा को निकालता है, तो निचले बाउंड को समावेशी और ऊपरी बाउंड को अनन्य बनाता है । यह इसे उन तरीकों के अनुरूप बना देगा String.substring(start, end)जो उसी तरह से संचालित होते हैं। आप इस तरह का व्यवहार करने के लिए सूर्य जेडडीके में इन सभी प्रकार के तरीकों को प्राप्त करेंगे क्योंकि यह विभिन्न ऑपरेशनों को शामिल करता है जिसमें सरणियों के अनुरूप तत्व शामिल हैं, जहां सूचक शून्य ( समावेशी ) से लेकर सरणी की लंबाई ( अनन्य ) तक हैं।

तो आपकी कुछ पसंदीदा रक्षात्मक प्रथाएं क्या हैं?

अद्यतन: यदि आप पहले से ही नहीं हैं, तो बेझिझक झंकार करें। मैं आधिकारिक जवाब चुनने से पहले अधिक प्रतिक्रियाओं का मौका दे रहा हूं ।


मैं यहाँ अज्ञानी 30% का प्रतिनिधित्व करना चाहता हूँ जो कि सरल तकनीकों को नहीं जानते होंगे । किसी के पास "स्पष्ट" तकनीकों का लिंक है जिसे हर किसी को एक नींव के रूप में जानना चाहिए?
elliot42


आप आधिकारिक उत्तर क्यों चुनेंगे? यह सिर्फ पूरी तरह से चाचा लगता है।
bzlm

खैर, जब प्रोग्रामिंग की बात आती है, तो भी चतुराई से "कम से कम विस्मय के नियम" के सम्मान में एक सीट लेनी चाहिए। मेरे लिए सबसे अच्छा जवाब चिह्नित करने के स्टैक ओवरफ्लो भावना के साथ तोड़ना स्टैक ओवरफ्लो प्रोटोकॉल का उल्लंघन करेगा (इसलिए ब्रेकिंग ने कहा नियम)। उस के अलावा: मैं बंद करना पसंद करता हूं :-)
रयान Delucchi

जवाबों:


103

सी ++ में, मैंने एक बार नए को फिर से परिभाषित करना पसंद किया था ताकि यह बाड़-पोस्ट त्रुटियों को पकड़ने के लिए कुछ अतिरिक्त मेमोरी प्रदान करे।

वर्तमान में, मैं टेस्ट ड्रिवेन डेवलपमेंट के पक्ष में रक्षात्मक प्रोग्रामिंग से बचना पसंद करता हूं । यदि आप जल्दी और बाहरी रूप से त्रुटियों को पकड़ते हैं, तो आपको रक्षात्मक युद्धाभ्यास के साथ अपने कोड को मैला-अप करने की आवश्यकता नहीं है, आपका कोड DRY -er है और आप कम त्रुटियों के साथ हवा-अप करते हैं जिन्हें आपको बचाव करना है।

विकीवॉन्लेज के रूप में लिखा :

रक्षात्मक प्रोग्रामिंग से बचें, इसके बजाय विफल फास्ट।

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


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

5
इर्रर ... ध्यान दें कि रक्षात्मक प्रोग्रामिंग की यह परिभाषा प्रश्न में निहित परिभाषा के करीब भी नहीं है।
सोल

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

6
मैं तर्क दूंगा कि "तेजी से विफल" प्रक्रिया रक्षात्मक प्रोग्रामिंग का एक रूप है।
रयान डेलूची

6
@ आर्यन बिल्कुल सही है, तेजी से असफल एक अच्छा रक्षात्मक अवधारणा है। यदि आप जिस राज्य में हैं, वह संभव नहीं है, तो साथ में सीमित रखने की कोशिश न करें, विफल और लोड! यदि आप मेटा-डेटा चालित हैं तो अतिरिक्त महत्वपूर्ण है। रक्षात्मक प्रोग्रामिंग सिर्फ आपके मापदंडों की जाँच नहीं कर रहा है ...
बिल K

75

एसक्यूएल

जब मुझे डेटा हटाना होता है, तो मैं लिखता हूं

select *    
--delete    
From mytable    
Where ...

जब मैं इसे चलाता हूं, तो मुझे पता चल जाएगा कि मैं भूल गया हूं या कहां से खंडित हूं। मेरी एक सुरक्षा है। यदि सब कुछ ठीक है, तो मैं '-' टिप्पणी टोकन के बाद सब कुछ उजागर करता हूं, और इसे चलाता हूं।

संपादित करें: यदि मैं बहुत अधिक डेटा हटा रहा हूं, तो मैं सिर्फ * के बजाय गिनती (*) का उपयोग करूंगा


मैंने इसे अपने iPhone पर लिखा है, जहां मैं टेक्स्ट का चयन नहीं कर सकता। यदि कोई मेरे कोड को कोड के रूप में चिह्नित कर सकता है, तो यह वास्तव में सराहना होगी। धन्यवाद।
जॉन मैकइंटायर

6
मैं इसे सिर्फ एक लेन-देन में लपेटता हूं ताकि अगर मैं
खराब हो जाऊं

36
BEGIN परिवहन | रोलबैक
ट्रांज़ैक्शन

3
+1 हां, मुझे लगता है कि इसे लेनदेन के साथ बदला जा सकता है, लेकिन मुझे इसे इस तरह से करने की सरलता पसंद है।
रयान डेलूची

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

48

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

इसका उपयोग कुछ गंभीर होने की स्थिति में किया जा सकता है और आपको समाप्त करने की आवश्यकता होती है।

इस मेमोरी को सामने से आवंटित करने से आपको एक सुरक्षा-जाल प्रदान होता है, क्योंकि आप इसे खाली कर सकते हैं और फिर निम्न करने के लिए उपलब्ध मेमोरी का उपयोग कर सकते हैं:

  • सभी लगातार डेटा सहेजें
  • सभी उपयुक्त फ़ाइलों को बंद करें
  • लॉग फ़ाइल में त्रुटि संदेश लिखें
  • उपयोगकर्ता के लिए एक सार्थक त्रुटि प्रस्तुत करें

मैंने इसे वर्षा दिवस निधि कहा है।
प्लिंथ

42

हर स्विच स्टेटमेंट जिसमें डिफ़ॉल्ट केस नहीं है, मैं एक केस जोड़ता हूं जो प्रोग्राम को एरर मैसेज के साथ निरस्त कर देता है।

#define INVALID_SWITCH_VALUE 0

switch (x) {
case 1:
  // ...
  break;
case 2:
  // ...
  break;
case 3:
  // ...
  break;
default:
  assert(INVALID_SWITCH_VALUE);
}

2
या आधुनिक फंसी हुई भाषा में एक फेंक।
टॉम हॉकिन - 14

2
अभिकर्ता का यह लाभ है कि इसके प्रभाव संकलन-समय पर विश्व स्तर पर अक्षम हो सकते हैं। फिर भी, कुछ स्थितियों में फेंक अधिक उपयुक्त हो सकता है, अगर आपकी भाषा इसका समर्थन करती है।
डायोमिडिस स्पिनेलिस

2
Assert का एक और फायदा है जो इसे उत्पादन कोड के लिए उपयोगी बनाता है: जब कुछ गलत हो जाता है, तो यह आपको बताता है कि क्या विफल हुआ और प्रोग्राम की कौन सी पंक्ति त्रुटि आई। एक बग रिपोर्ट जैसी अद्भुत है!
मेसन व्हीलर

2
@Diomidis: एक और कोण है: Assert का नुकसान यह है कि इसका प्रभाव संकलन-समय पर वैश्विक रूप से अक्षम हो सकता है।
मोहभंग

1
फेंक वास्तव में बेहतर है। और फिर आप सुनिश्चित करें कि आपका परीक्षण कवरेज पर्याप्त है।
डोमिनिक क्रोनिन

41

जब आप किसी एनम (C #) के विभिन्न राज्यों को संभाल रहे हैं:

enum AccountType
{
    Savings,
    Checking,
    MoneyMarket
}

फिर, कुछ दिनचर्या के अंदर ...

switch (accountType)
{
    case AccountType.Checking:
        // do something

    case AccountType.Savings:
        // do something else

    case AccountType.MoneyMarket:
        // do some other thing

    default:
-->     Debug.Fail("Invalid account type.");
}

कुछ बिंदु पर मैं इस एनम में एक और खाता प्रकार जोड़ूंगा। और जब मैं करता हूं, तो मैं इस स्विच स्टेटमेंट को ठीक करना भूल जाऊंगा। तो Debug.Failइस तथ्य की ओर मेरा ध्यान आकर्षित करने के लिए क्रैश (डिबग मोड में)। जब मैं इसे जोड़ता हूं case AccountType.MyNewAccountType:, तो भयानक दुर्घटना रुक जाती है ... जब तक मैं एक और खाता प्रकार नहीं जोड़ता और यहां के मामलों को अपडेट करना भूल जाता हूं।

(हाँ, बहुरूपता शायद यहाँ बेहतर है, लेकिन यह मेरे सिर के ऊपर से एक उदाहरण मात्र है।)


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

सी में, मैं अंत में एक अमान्य खाता टाइप करता था। यह कभी-कभी उपयोगी होता है।
रे तयेक

1
@ एडाम - कंपाइलर एक चेतावनी जारी करेगा यदि आप सब कुछ फिर से जोड़ते हैं । यदि आप नई कक्षाएं और केवल आंशिक रूप से recompile जोड़ते हैं, तो आपको ऊपर की तरह कुछ नोटिस नहीं हो सकता है, और डिफ़ॉल्ट मामला आपको बचाएगा। यह चुपचाप विफल नहीं होगा।
एडी

4
ब्रेक को टिप्पणी, स्लेशीन में निहित किया गया है। : पी
रयान लुन्डी

2
डिबग के बाद प्रोडक्शन कोड के लिए 'थ्रो न्यू नोटस्प्रेड एक्ससेप्शन ()' होना चाहिए।
user7116

35

जब एक स्ट्रिंग के साथ त्रुटि संदेश प्रिंट करना (विशेष रूप से एक जो उपयोगकर्ता इनपुट पर निर्भर करता है), मैं हमेशा एकल उद्धरण का उपयोग करता हूं ''। उदाहरण के लिए:

FILE *fp = fopen(filename, "r");
if(fp == NULL) {
    fprintf(stderr, "ERROR: Could not open file %s\n", filename);
    return false;
}

चारों ओर उद्धरणों की यह कमी %sवास्तव में खराब है, क्योंकि कहते हैं कि फ़ाइल नाम एक रिक्त स्ट्रिंग है या सिर्फ व्हाट्सएप या कुछ है। निश्चित रूप से मुद्रित संदेश होगा:

ERROR: Could not open file

तो, हमेशा बेहतर करने के लिए:

fprintf(stderr, "ERROR: Could not open file '%s'\n", filename);

फिर कम से कम उपयोगकर्ता इसे देखता है:

ERROR: Could not open file ''

मुझे लगता है कि यह अंतिम उपयोगकर्ताओं द्वारा प्रस्तुत बग रिपोर्ट की गुणवत्ता के मामले में बहुत बड़ा अंतर है। यदि कुछ सामान्य ध्वनि के बजाय इस तरह का एक अजीब-सा त्रुटि संदेश है, तो वे इसे केवल "मेरी फ़ाइलें नहीं खोलेंगे" लिखने के बजाय इसे कॉपी / पेस्ट करने की अधिक संभावना है।


4
अच्छा एक, मैंने इस मुद्दे को भी देखा है
एलेक्स बारानोस्की

28

SQL सुरक्षा

किसी भी एसक्यूएल को लिखने से पहले जो डेटा को संशोधित करेगा, मैं पूरी चीज़ को एक लुढ़के हुए लेन-देन में लपेटता हूं:

BEGIN TRANSACTION
-- LOTS OF SCARY SQL HERE LIKE
-- DELETE FROM ORDER INNER JOIN SUBSCRIBER ON ORDER.SUBSCRIBER_ID = SUBSCRIBER.ID
ROLLBACK TRANSACTION

यह आपको एक खराब डिलीट / अपडेट को स्थायी रूप से निष्पादित करने से रोकता है। और, आप पूरी चीज़ को निष्पादित कर सकते हैं और उचित रिकॉर्ड की संख्या को सत्यापित कर सकते हैं या SELECTअपनी SQL के बीच बयान जोड़ सकते हैं और ROLLBACK TRANSACTIONयह सुनिश्चित करने के लिए कि सब कुछ सही लग रहा है।

जब आप पूरी तरह से कर रहे हैं यकीन है कि यह है कि आप क्या उम्मीद, बदलने ROLLBACKके लिए COMMITऔर असली के लिए चलाते हैं।


तुम मुझे इस एक पर मुक्का मारो! :-)
हॉवर्ड पिंसले

2
मैं हर समय ऐसा करता था, लेकिन यह डीबी क्लस्टर्स पर इतना अतिरिक्त ओवरहेड का कारण बनता है कि मुझे रोकना पड़ा।
ज़ेन लिंक्स

25

सभी भाषाओं के लिए:

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


5
वास्तव में एस्चेव भाग का क्या मतलब है? मैं कभी-कभी उन वैरिएबल का परिचय देता हूं जो केवल अगली पंक्ति तक रहते हैं। वे एक अभिव्यक्ति के लिए एक नाम के रूप में काम करते हैं, जो कोड को अधिक पठनीय बनाता है।
जूल

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

1
मैं मानता हूं कि ऐसे असाधारण मामले हैं जहां मैं स्पष्टता के लिए चर घोषित करता हूं (और कभी-कभी डिबगिंग के लिए एक लक्ष्य बनाने के लिए)। मेरा अनुभव है कि सामान्य अभ्यास विपरीत दिशा में गलत करना है।
dkretz

मैं दोनों दृष्टिकोणों से सहमत हूं; हालांकि जब मैं भावों को अस्थायी चर में तोड़ता हूं तो मैं एक अलग दायरे में ऐसा करने की कोशिश करता हूं। लैंबडा इसके लिए महान हैं, जैसा कि सहायक तरीके हैं।
एरिक फोर्ब्स

19

जब संदेह में, आवेदन बम!

चेक प्रत्येक और हर की शुरुआत में पैरामीटर हर विधि (explictly यह अपने आप कोडिंग, या अनुबंध-आधारित प्रोग्रामिंग का उपयोग कर कि क्या यहाँ बात नहीं करता है) और अगर कोड में कोई भी पूर्व शर्त है सही अपवाद और / या सार्थक त्रुटि संदेश के साथ बम नहीं मिले।

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


और निश्चित रूप से: इस आसान को बनाने के लिए जेनेरिक कोड (C # में एक छोटा पुस्तकालय, विस्तार विधियाँ, जो भी हो) का उपयोग करें। तो आप param.NotNull("param")इसके बजाय somethin glike लिख सकते हैंif ( param == null ) throw new ArgumentNullException("param");
peSHIr

2
या कल्पना # की तरह अनुबंध आधारित प्रोग्रामिंग का उपयोग करें!
bzlm

निर्भर करता है कि यह क्या अनुप्रयोग है। मुझे उम्मीद है कि फ्लाई-बाय-वायर विमान और पेसमेकर के लिए कोड लिखने वाले लोग peSHIr की तरह नहीं सोचते हैं।
मार्कज

6
@ मर्कज: आप वास्तव में इसे प्राप्त नहीं करते हैं, क्या आप? यदि यह जल्दी (= विकासशील और परीक्षण के दौरान) बमबारी करता है तो इसे कभी भी उत्पादन में नहीं होना चाहिए। इसलिए मैं वास्तव में वे आशा करते हैं इस तरह कार्यक्रम!
peSHIr

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

18

जावा में, विशेष रूप से संग्रह के साथ, एपीआई का उपयोग करें, इसलिए यदि आपकी विधि प्रकार सूची (उदाहरण के लिए) लौटाती है, तो निम्न प्रयास करें:

public List<T> getList() {
    return Collections.unmodifiableList(list);
}

अपनी कक्षा से बचने के लिए कुछ भी न दें जो आपको करने की आवश्यकता नहीं है!


+1 C # में इसके लिए आसानी से संग्रह हैं।
tobsen

1
जावा के लिए +1। मैं इसका हर समय उपयोग करता हूं
फॉर्च्युनर

+1 ... मैं यह बहुत करता हूं (हालांकि मैं चाहता हूं कि अधिक लोग ऐसा करना याद रखें)।
रयान डेलुची

बस सुनिश्चित करें कि कुछ और नहीं अंतर्निहित सूची चर का एक उदाहरण है, या यह आपको बहुत अच्छा नहीं करेगा ...
GreenieMeanie

5
FYI करें, Collections.unmodifiableList सूची का एक अपरिवर्तनीय दृश्य लौटाता है , एक अपरिवर्तनीय प्रति नहीं । इसलिए यदि मूल सूची संशोधित हो जाती है, तो दृश्य होगा!
जरकोनेंन

17

पर्ल में, हर कोई करता है

use warnings;

मुझे पसंद है

use warnings FATAL => 'all';

यह किसी भी संकलक / रनटाइम चेतावनी के लिए कोड को मरने का कारण बनता है। यह ज्यादातर असिंचित तारों को पकड़ने में उपयोगी है।

use warnings FATAL => 'all';
...
my $string = getStringVal(); # something bad happens;  returns 'undef'
print $string . "\n";        # code dies here

काश यह थोड़ा और अधिक विज्ञापित होता ...
DJG

16

सी#:

string myString = null;

if (myString.Equals("someValue")) // NullReferenceException...
{

}

if ("someValue".Equals(myString)) // Just false...
{

}

जावा में ही, और शायद सबसे ज्यादा ओओ भाषा।
मिनीक्वार

यह ऑब्जेक्टिव-सी में अच्छा है, जहां शून्य ("एक निश्चित लाइसेंस के साथ" अशक्त वस्तु के कॉल तरीके) संदेश भेजना संभव है। [Nil isEqualToString: @ "Moo"] को कॉल करना गलत है।
जूल

मैं C # उदाहरण से असहमत हूं। एक अच्छा समाधान "अगर (myString ==" someValue ")" का उपयोग करना है। इसके अलावा कोई अशक्त संदर्भ अपवाद नहीं है, और निश्चित रूप से अधिक पठनीय है।
डेन सी।

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

2
C # में, मैं हमेशा string.Equals (<string1>, <string2>) का उपयोग करता हूं। इससे कोई फर्क नहीं पड़ता कि उनमें से कोई भी अशक्त है।
डार्सी कैसलेमैन

15

स्ट्रिंग की किसी भी जाँच करने से पहले स्ट्रिंग की c # चेकिंग में करें। लंबाई, इंडेक्सऑफ, मिड आदि जैसे किसी भी ऑपरेशन को करने से पहले खाली करें।

public void SomeMethod(string myString)
{
   if(!string.IsNullOrEmpty(myString)) // same as myString != null && myString != string.Empty
   {                                   // Also implies that myString.Length == 0
     //Do something with string
   }
}

[संपादित करें]
अब मैं .NET 4.0 में निम्न कार्य भी कर सकता हूं, इसके अतिरिक्त यदि मान सिर्फ व्हाट्सएप है तो चेक करता है

string.IsNullOrWhiteSpace(myString)

7
यह रक्षात्मक नहीं है, यह समस्या की अनदेखी कर रहा है। होना चाहिए if (!string.IsNullOrEmpty(myString)) throw new ArgumentException("<something>", "myString"); /* do something with string */
enashnash 16

14

जावा और सी # में, हर धागे को एक सार्थक नाम दें। इसमें थ्रेड पूल धागे शामिल हैं। यह स्टैक डंप को और अधिक सार्थक बनाता है। थ्रेड पूल थ्रेड्स को एक सार्थक नाम देने के लिए यह थोड़ा अधिक प्रयास करता है, लेकिन अगर एक थ्रेड पूल को लंबे समय तक चलने वाले एप्लिकेशन में कोई समस्या है, तो मैं स्टैक डंप होने का कारण बन सकता हूं (आप SendSignal.exe के बारे में जानते हैं , सही है? ), लॉग को पकड़ो, और एक चल प्रणाली को बाधित किए बिना मैं बता सकता हूं कि कौन से धागे हैं ... जो भी हो। डेडलॉक किया गया, लीक हो रहा है, बढ़ रहा है, जो भी समस्या है।


और - विंडोज पर - सी ++ के लिए भी! (विशेष एसईएच अपवाद फेंक और निम्नलिखित कैच के साथ सक्षम)।
ब्रायन हाक

12

VB.NET के साथ, ऑप्शन एक्सप्लिक्ट और ऑप्शन स्ट्रिक्ट को डिफ़ॉल्ट रूप से पूरे विज़ुअल स्टूडियो के लिए स्विच किया जाता है।


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

1
वैसे, पुराने कोड को परिवर्तित करने वाले किसी भी व्यक्ति के लिए विकल्प स्ट्रिक्ट का उपयोग नहीं किया गया था, ध्यान दें कि स्ट्रिंग के लिए ऑटोकॉनवर्ट की गई वस्तुओं के मामले में, वे ToString () का उपयोग नहीं कर रहे हैं; वे एक कलाकार को स्ट्रिंग का उपयोग कर रहे हैं। अपने शुरुआती .NET दिनों में मैं इन्हें ToString () का उपयोग करने के लिए बदलूंगा, और यह चीजों को तोड़ देगा, विशेष रूप से एनम के साथ।
रयान लुनडी

10

सी ++

#define SAFE_DELETE(pPtr)   { delete pPtr; pPtr = NULL; }
#define SAFE_DELETE_ARRAY(pPtr) { delete [] pPtr; pPtr = NULL }

इसके बाद अपने सभी ' डिलीट पीपीपीआर ' और ' डिलीट [] पीपीपीआर ' कॉल को SAFE_DELETE (pPtr) और SAFE_DELETE_ARRAY (pPtr) से बदलें

अब गलती से अगर आप पॉइंटर 'ptr' का उपयोग करने के बाद उसे हटा देते हैं, तो आपको 'एक्सेस उल्लंघन' त्रुटि मिलेगी। यादृच्छिक स्मृति भ्रष्टाचारों की तुलना में इसे ठीक करना बहुत आसान है।


1
बेहतर एक टेम्पलेट का उपयोग करें। यह स्कोप और अधिभार है।

मैं भी अभी यही कहने वाला था। मैक्रो के बजाय टेम्पलेट का उपयोग करें। इस तरह यदि आपको कभी भी कोड के माध्यम से कदम बढ़ाने की आवश्यकता है, तो आप कर सकते हैं।
स्टीव रोवे

मैंने सीखा कि स्कूल में कठिन रास्ते पर बहस करना आसान था। यह एक गलती है जिसके बाद से मैं नहीं बना हूं। :)
ग्रेग डी

3
या स्मार्ट पॉइंटर्स का उपयोग करें ... या बिल्ली, नए / हटाने से बचें जितना आप कर सकते हैं।
अरफांगियन

1
@ प्रारूप: बस से बचें delete। उपयोग करना newठीक है, जब तक कि नया ऑब्जेक्ट स्मार्ट पॉइंटर के स्वामित्व में हो जाता है।
अलेक्जेंड्रे सी।

10

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

private Object someHelperFunction(Object param)
{
    assert param != null : "Param must be set by the client";

    return blahBlah(param);
}

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


.NET में, Debug.Assert एक ही काम करता है। जब भी आप एक जगह है जहाँ आपको लगता है "यह संदर्भ अशक्त यहाँ नहीं किया जा सकता, है ना?", आप एक Debug.Assert वहाँ रख सकते हैं, इतना है कि यह करता है, तो कर सकते हैं अशक्त हो, आप या तो बग को ठीक करने या अपने मान्यताओं बदल सकते हैं।
रायन लूनी

1
+1, सार्वजनिक तरीकों को अनुबंध विफलताओं पर फेंकना चाहिए, निजीकरण को जोर देना चाहिए
उपयोगकर्ता 7116

9

मैं नहीं मिला readonlyजब तक मैं ReSharper पाया कीवर्ड, लेकिन मैं अब विशेष रूप से सेवा कक्षाओं के लिए सहज इसका इस्तेमाल,।

readonly var prodSVC = new ProductService();

मैं उन सभी क्षेत्रों पर जावा के समकक्ष 'अंतिम' कीवर्ड का उपयोग करता हूं जो मैं कर सकता हूं। यह वास्तव में आपको बोनहेड चालें बनाने से बचाता है जैसे फ़ील्ड सेट न करना / भ्रमित करने वाले स्विच लिखना जो कई बार फ़ील्ड सेट कर सकते हैं। मुझे स्थानीय वेरिबल्स / मापदंडों को चिह्नित करने की कम संभावना है, लेकिन मुझे लगता है कि यह चोट नहीं पहुंचा सकता।
डाकू प्रोग्रामर

सी # आप केवल पढ़ने के रूप में स्थानीय चर चिह्नित करने के लिए है, तो हम भी विकल्प ... की जरूरत नहीं है की अनुमति नहीं है
जेसन Punyon

मुझे यकीन नहीं है कि यहां आसानी से क्या मतलब है, लेकिन मेरे लिए जावा का फाइनल पर्याप्त नहीं है। इसका मतलब सिर्फ इतना है कि किसी वस्तु का सूचक अपरिवर्तित है, लेकिन स्वयं वस्तु पर परिवर्तन को रोकने का कोई तरीका नहीं है।
Slartibartfast

C # में एक पठनीय संरचना इसे कभी भी बदलने से रोकती है।
शमूएल

9

जावा में, जब कुछ हो रहा है और मुझे पता नहीं क्यों, मैं कभी-कभी इस तरह Log4J का उपयोग करूंगा:

if (some bad condition) {
    log.error("a bad thing happened", new Exception("Let's see how we got here"));
}

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


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

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

2
आप नए अपवाद ("संदेश") का उपयोग भी कर सकते हैं। PrintStackTrace (); कोई फेंकने या पकड़ने की आवश्यकता नहीं है, लेकिन आपको अभी भी लॉग में एक अच्छा स्टैकट्रेस मिलता है। जाहिर है, यह उत्पादन कोड में नहीं होना चाहिए, लेकिन यह डीबगिंग के लिए बहुत उपयोगी हो सकता है।
Jorn

9

यदि आप Visual C ++ का उपयोग कर रहे हैं, तो जब भी आप बेस क्लास की विधि को ओवर-राइड करते हैं , तो ओवरराइड कीवर्ड का उपयोग करें। इस तरह अगर कोई भी कभी भी आधार वर्ग के हस्ताक्षर को बदलने के लिए होता है, तो वह गलत तरीके से चुपचाप बुलाए जाने के बजाय एक संकलक त्रुटि को फेंक देगा। अगर यह पहले से मौजूद होता तो इससे मुझे कुछ समय की बचत होती।

उदाहरण:

class Foo
{
   virtual void DoSomething();
}

class Bar: public Foo
{
   void DoSomething() override { /* do something */ }
}

Java के लिए, यह वर्ग Foo {void doSomething () {}} class बार {@Override void doSomething () {}} चेतावनी देगा यदि यह एनोटेशन गुम है (तो आप चुपचाप एक विधि को ओवरराइड नहीं कर सकते हैं जो आपने नहीं किया है मतलब है) और जब एनोटेशन होता है, लेकिन यह कुछ भी ओवरराइड नहीं करता है।
Jorn

अच्छा ... मैं इस बारे में नहीं जानता था ... बहुत बुरा यह Microsoft विशिष्ट लगता है ... लेकिन कुछ अच्छे #defines इसे पोर्टेबल बनाने में मदद कर सकते हैं
e.tadeu

8

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

इसने कुछ दौड़ की स्थितियों और छद्म गतिरोध की स्थितियों को अलग करने में मदद की है जो कि ऐसा करने से पहले मैं रहस्यमय था।


1
इस तरह उपयोग किए जाने वाले टाइमआउट के साथ प्रतीक्षा अन्य, बदतर, समस्याओं का संकेत है।
डिक्रोस

2
ऐसी प्रणाली जिसमें उच्च अपटाइम होना आवश्यक है, कम से कम नैदानिक ​​जानकारी प्राप्त करना बेहतर है ताकि आप समस्या का पता लगा सकें। कभी-कभी आप किसी थ्रेड से बाहर निकलना पसंद करते हैं या सिस्टम के ज्ञात स्थिति में होने पर कॉलर को प्रतिक्रिया देना चाहते हैं, इसलिए आप एक सेमाफोर पर प्रतीक्षा करते हैं। लेकिन आप हमेशा के लिए लटकना नहीं चाहते
एडी

8

सी#

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

8

जब आप एक त्रुटि संदेश जारी करते हैं, तो कम से कम वही जानकारी प्रदान करने का प्रयास जब प्रोग्राम ने त्रुटि को फेंकने का निर्णय किया था।

"अनुमति अस्वीकृत" आपको बताता है कि अनुमति की समस्या थी, लेकिन आपको पता नहीं है कि समस्या क्यों या कहाँ हुई। "लेन-देन लॉग / मेरी / फाइल नहीं लिख सकते: केवल-पढ़ने के लिए फाइल सिस्टम" कम से कम आपको यह पता करने की अनुमति देता है कि किस आधार पर निर्णय लिया गया था, भले ही वह गलत हो - खासकर अगर यह गलत है: गलत फ़ाइल नाम? गलत खोला? अन्य अप्रत्याशित त्रुटि? - और आपको बताती है कि समस्या होने पर आप कहां थे।


1
त्रुटि संदेश के लिए कोड लिखते समय, संदेश पढ़ें और पूछें कि आप आगे क्या जानना चाहते हैं , फिर इसे जोड़ें। अनुचित होने तक दोहराएं। उदाहरण के लिए: "सीमा से बाहर।" सीमा से बाहर क्या है? "फू रेंज से बाहर गिनती।" मूल्य क्या था? "फू गणना (42) सीमा से बाहर।" सीमा क्या है? "फू गणना (42) रेंज से बाहर (549 से 666)।"
HABO

7

C # में, का उपयोग करें as कास्ट करने के कीवर्ड का ।

string a = (string)obj

यदि अपवाद एक स्ट्रिंग नहीं है तो एक अपवाद फेंक देंगे

string a = obj as string

अगर अशक्त एक स्ट्रिंग नहीं है, तो एक अशक्त छोड़ देगा

आपको अभी भी अशक्त होने की आवश्यकता है, लेकिन यह आम तौर पर अधिक सीधे आगे है फिर कास्ट अपवादों की तलाश में है। कभी-कभी आप चाहते हैं "किस प्रकार का व्यवहार करें"(string)obj सिंटैक्स पसंद किया जाता है।

अपने स्वयं के कोड में, मुझे लगता है कि मैं asसमय के बारे में 75% वाक्यविन्यास का उपयोग करता हूं , और (cast)वाक्यविन्यास लगभग 25%।


सही, लेकिन अब आपको संदर्भ का उपयोग करने से पहले अशक्त के लिए जांचना होगा।
ब्रायन रासमुसेन

7
नहीं मिला। मुझे एक बुरा फैसला लगता है, अशक्त पसंद करने के लिए। मूल कारण के लिए कोई संकेत के साथ रनटाइम के दौरान आपको कहीं न कहीं समस्याएं मिलेंगी ।
काई हप्पमन

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

2
यह एक किले में बड़ी बॉलरूम खिड़कियों के रूप में रक्षात्मक लगता है। लेकिन यह एक सुंदर दृश्य है!
पोंटस गागे

1
यह मुझे किसी ऐसे व्यक्ति की याद दिलाता है जिसने अपवादों का उपयोग नहीं किया क्योंकि 'उन्होंने कार्यक्रम तोड़ दिए'। यदि आप कुछ व्यवहार चाहते हैं, जब कोई ऑब्जेक्ट एक वर्ग नहीं है जिसकी आप अपेक्षा करते हैं, तो मुझे लगता है कि मैं इसे दूसरे तरीके से कोड करूंगा। is/instanceofख्याल आना।
किर्स्टिन

6

किसी के लिए भी तैयार रहें इनपुट के , और जो भी इनपुट आपको मिले वह अप्रत्याशित है, लॉग में डंप करें। (कारण के भीतर। यदि आप उपयोगकर्ता से पासवर्ड पढ़ रहे हैं, तो उसे लॉग करने के लिए डंप न करें! और प्रति लॉग में लॉग करने के लिए हजारों प्रकार के संदेश लॉग न करें। आपके लॉग करने से पहले सामग्री और संभावना और आवृत्ति के बारे में कारण। ।)

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

इस प्रकार, यहां तक ​​कि जब आपको लगता है कि आप तार के दोनों सिरों को नियंत्रित करते हैं, तो आप बिना किसी खलनायक के अप्रत्याशित डेटा प्रारूप प्राप्त कर सकते हैं। तैयार रहें, रक्षात्मक रूप से कोड करें, और अप्रत्याशित इनपुट के मामले में नैदानिक ​​आउटपुट प्रदान करें।


6

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

में शीर्ष 25 सबसे खतरनाक प्रोग्रामिंग त्रुटियों "अनुचित इनपुट सत्यापन" खंड "के बीच अवयव असुरक्षित इंटरैक्शन" में सबसे खतरनाक गलती है।

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

अपरिवर्तनीयों को लागू करने के लिए , मैं किसी भी वर्ग में एक विधि लिखता हूं जो "वर्ग की संगति" की जांच करता है, जिसे पूर्वगामी और उत्तर-स्थूल मैक्रो द्वारा सैद्धांतिक रूप से कहा जाना चाहिए।

मैं कोड कॉन्ट्रैक्ट लाइब्रेरी का मूल्यांकन कर रहा हूं ।


6

जावा

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

कभी-कभी यह सुनिश्चित करने के लिए स्थानीय चर पर अंतिम उपयोग करना उपयोगी होता है कि वे अपने मूल्य को कभी नहीं बदलते हैं। मुझे यह बदसूरत, लेकिन आवश्यक लूप निर्माण में उपयोगी पाया गया। यह सिर्फ एक चर का पुन: उपयोग करने के लिए आसान है, भले ही यह एक स्थिर होना है।

अपने गेटअप में रक्षा प्रतिलिपि का उपयोग करें । जब तक आप एक आदिम प्रकार या एक अपरिवर्तनीय वस्तु नहीं लौटाते हैं, तो सुनिश्चित करें कि आप ऑब्जेक्ट को कॉपी करें ताकि एनकैप्सुलेशन का उल्लंघन न हो।

क्लोन का उपयोग कभी न करें, कॉपी कंस्ट्रक्टर का उपयोग करें ।

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


5

मैं echoकई बार PHP में लिखना भूल गया :

<td><?php $foo->bar->baz(); ?></td>
<!-- should have been -->
<td><?php echo $foo->bar->baz(); ?></td>

यह मुझे हमेशा के लिए लेने की कोशिश करेगा और पता लगाएगा कि क्यों -> बाज () कुछ भी वापस नहीं कर रहा था जब वास्तव में मैं इसे गूंज नहीं रहा था! : -तो मैंने एक ऐसा EchoMeवर्ग बनाया, जिसे किसी भी मूल्य के चारों ओर लपेटा जा सकता है, जिसे गूँजना चाहिए:

<?php
class EchoMe {
  private $str;
  private $printed = false;
  function __construct($value) {
    $this->str = strval($value);
  }
  function __toString() {
    $this->printed = true;
    return $this->str;
  }
  function __destruct() {
    if($this->printed !== true)
      throw new Exception("String '$this->str' was never printed");
  }
}

और फिर विकास के माहौल के लिए, मैंने उन चीजों को लपेटने के लिए एक इकोमे का उपयोग किया, जिन्हें मुद्रित किया जाना चाहिए:

function baz() {
  $value = [...calculations...]
  if(DEBUG)
    return EchoMe($value);
  return $value;
}

उस तकनीक का उपयोग करते हुए, पहला उदाहरण जो echoअब गायब है, वह एक अपवाद फेंक देगा ...


क्या इस $ के लिए विध्वंसक जांच नहीं होनी चाहिए-> मुद्रित! == सच?
कर्स्टन

आपको टेम्पलेट सिस्टम का उपयोग करने पर विचार करना चाहिए, HTML में php एम्बेड करना लगभग सभी प्रणालियों पर उप-इष्टतम है।
क्रूचन

शायद मुझे कुछ याद आ रहा है? लेकिन यह मुझे ऐसा लगता है जैसे कोडिंग के लिए क्षतिपूर्ति करने की कोशिश कर रहा है: AnObject.ToStringइसके बजाय Writeln(AnObject.ToString)?
मोहभंग हुआ

हां, लेकिन गलती बहुत आसान है PHP में
बहुत ज्यादा php

4

सी ++

जब मैं नया टाइप करता हूं, तो मुझे तुरंत डिलीट टाइप करना होगा। खासकर सरणियों के लिए।

सी#

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


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

5
C ++ में, जब आप नया टाइप करते हैं, तो आपको तुरंत उस पॉइंटर को एक AutoPtr या संदर्भ-गणना किए गए कंटेनर में असाइन करना चाहिए। सी ++ में विनाशकारी और टेम्पलेट हैं; विलोपन को स्वचालित रूप से संभालने के लिए उन्हें बुद्धिमानी से उपयोग करें।
जनवरी'09

4

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

इसके अलावा, linux पर 'strace -p [pid]' आपको दिखाएगा कि सिस्टम कॉल प्रक्रिया (या linux थ्रेड) बना रहा है। यह पहली बार में अजीब लग सकता है, लेकिन एक बार जब आप सिस्टम कॉल का उपयोग करने लगते हैं, तो आम तौर पर जो कॉल करता है, वह आपको इस निदान के लिए अमूल्य लगेगा।

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