अलविदा अगर $ DEBUG!

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



    लेकिन दूसरी समस्या से काफी सफलतापूर्वक लड़ा जा सकता है:

    warn "i=$i\n" if $DEBUG;





    इस मामले में, प्रदर्शन हानि जब $DEBUG==0



    एक स्केलर की जाँच करने तक सीमित होती है, अर्थात। वास्तव में, कोड इस प्रकार है:

    0;







    दुर्भाग्य से, यह निर्णय इस तथ्य की ओर जाता है कि "अतिरिक्त" कोड और भी बड़ा हो जाता है: if $DEBUG



    ऐसी प्रत्येक पंक्ति में जोड़ा जाता है। कभी-कभी if



    इसे फंक्शन में बुलाया जा रहा है, if



    इसे आगे बढ़ाकर इसे लड़ने का प्रयास करें

    sub log { return if !$DEBUG; warn "$_[0]\n"; }

    log("i=$i");






    दुर्भाग्य से, प्रदर्शन में काफी गिरावट आई है। अदिश की जाँच करने के लिए फ़ंक्शन में इनपुट / आउटपुट भी जोड़ा जाता है। और चूंकि $DEBUG



    के अस्तित्व का कारण यह है कि प्रदर्शन गिरता नहीं है, यह विधि आमतौर पर लोकप्रिय नहीं है।



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



    मैं इस समस्या को हल करने के लिए आपके ध्यान में एक और तरीका लाना चाहता हूं:

    BEGIN {

    *log = $ENV{DEBUG} ? sub {warn "@_"} : sub () {0};

    }

    log+ "data", 123;







    विचार यह है कि जब डिबगिंग मोड को अक्षम किया जाता है, तो log



    फ़ंक्शन को एक स्थिरांक के रूप में परिभाषित किया जाता है, जबकि पर्ल निरंतर कार्यों को अनुकूलित किया जाता है और उन्हें कॉल करने के बजाय उनके मूल्यों के लिए कोड में प्रतिस्थापित किया जाता है। ( BEGIN { *log = sub () {0} }



    कोड BEGIN { *log = sub () {0} }



    use constant log => 0;



    का use constant log => 0;



    करने के use constant log => 0;



    समान है use constant log => 0;



    ) नतीजतन, वास्तविक कोड जो पर्ल निष्पादित करेगा वह है:

    log( +"data", 123 ); # if $ENV{DEBUG}

    0 + "data", 123; # if !$ENV{DEBUG}







    परिणामस्वरूप, हमें if $DEBUG



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



    दुर्भाग्य से, इस विकृति के दो दुष्प्रभाव हैं। गैर-संख्याओं को जोड़ने के प्रयासों पर पहला - चेतावनी चेतावनियों का उपयोग करें। दूसरा - if $DEBUG



    विकल्प की तुलना में यह विधि अभी भी थोड़ी धीमी है, क्योंकि डिबग मोड अक्षम होने पर भी लॉग फ़ंक्शन के तर्कों का मूल्यांकन किया जाता है।



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



All Articles