सख्त और चेतावनी का उपयोग क्यों करें?


104

यह मुझे लगता है कि पर्ल टैग में कई सवालों को हल किया जा सकता है अगर लोग उपयोग करेंगे:

use strict;
use warnings;

मुझे लगता है कि कुछ लोग इन्हें प्रशिक्षण पहियों, या अनावश्यक जटिलताओं के समान मानते हैं, जो स्पष्ट रूप से सच नहीं है, क्योंकि बहुत कुशल पर्ल प्रोग्रामर भी उनका उपयोग करते हैं।

ऐसा लगता है कि ज्यादातर लोग जो पर्ल में प्रवीण हैं, वे हमेशा इन दो कौशलों का उपयोग करते हैं, जबकि जो लोग शायद ही कभी इनका उपयोग करते हैं उन्हें फायदा होता है। तो, मैंने सोचा कि यह जब करने के लिए लोगों को प्रोत्साहित करने के लिए लिंक करने के लिए एक सवाल है करने के लिए एक अच्छा विचार होगा use strictऔर warnings

तो, क्यों एक पर्ल डेवलपर use strictऔर चाहिए warnings?


14
मैं हमेशा इस तरह के सामान के लिए आश्चर्यचकित होता हूं कि वे सिर्फ इसे डिफ़ॉल्ट क्यों नहीं बनाते हैं और देव को वास्तव में सामान को सक्रिय रूप से ढीला करना पड़ता है, जहांuse loose;
पॉल टिनग

12
कई शांत और उपयोगी चीजों की तरह, पर्ल एक हैक के रूप में शुरू हुआ, उस व्यक्ति के लिए एक उपकरण के रूप में जिसने इसे लागू किया। बाद में यह अधिक लोकप्रिय हो गया और अकुशल लोगों की बढ़ती संख्या ने इसका उपयोग करना शुरू कर दिया। ऐसा तब होता है जब आप कुछ सोचना शुरू करते हैं जैसे use strictकि एक अच्छा विचार था लेकिन पीछे की संगतता पहले से ही आपके लिए एक वास्तविक समस्या बन गई है :-(
डैनियल बॉहेर

14
use strict;जब आप Perl 5.12 (या उच्चतर) भाषा का अनुरोध करते हैं तो @JB Nizet, @Paul T, वास्तव में, डिफ़ॉल्ट रूप से होता है। कोशिश करो perl -e"use v5.012; $x=123;"no strict;वास्तव में इसे बंद कर देता है।
इकेगामी

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

5
@JoelBerger नहीं, वास्तव में यह ऐसा कुछ नहीं है। जैसा मैंने कहा, शीर्षक में केवल इसी तरह के शब्द हैं। यह पश्चगामी अनुकूलता के लिए है। स्वीकार किए गए उत्तर में पहला वाक्य है, आप कैसे प्रस्ताव करते हैं जो मेरे प्रश्न पर लागू होता है?
टीएलपी

जवाबों:


83

शुरुआत के लिए, use strict;(और कुछ हद तक use warnings;) , चर नामों में टाइपोस खोजने में मदद करता है। यहां तक ​​कि अनुभवी प्रोग्रामर भी ऐसी त्रुटियां करते हैं। एक सामान्य मामला कोड की सफाई या रीफैक्टरिंग करते समय एक चर का उदाहरण बदलना भूल जाता है।

का उपयोग करते हुए use strict; use warnings; कई त्रुटियों जल्दी ही कैच की तुलना में वे अन्यथा जो यह आसान त्रुटियों के मूल कारणों को खोजने के लिए बनाता पकड़ा किया जाएगा। मूल कारण एक त्रुटि या सत्यापन जाँच की आवश्यकता हो सकती है, और यह बिना किसी प्रोग्रामर या कौशल के हो सकता है।

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


संबंधित पढ़ना: क्यों उपयोग करें my?


2
@ टीएलपी, मैं यह अध्ययन करने के लिए नहीं हूँ कि यह कितना मदद करता है। यह कहना पर्याप्त होगा कि वे बिना शर्त मदद करते हैं।
इकेगामी

1
इसे वैकल्पिक क्यों बनाया गया है अगर इसके इतने सारे लाभ हैं? इसे डिफ़ॉल्ट रूप से सक्षम क्यों नहीं किया गया (जैसे किसी ने ऊपर टिप्पणी की)? क्या यह संगतता कारणों से है?
जीन

4
@ जीन, पीछे की संगतता। ध्यान दें कि use strict;यदि आप संस्करण 5.12 या भाषा के नए ( use 5.012;) का उपयोग करते हैं तो डिफ़ॉल्ट रूप से सक्षम है ।
ikegami

@ जीन यदि आप एक साधारण स्क्रिप्ट लिख रहे हैं, तो आप वास्तव में फ़ाइल हैंडलर नामों के बारे में चेतावनियों से सचेत नहीं होना चाहते हैं या उनके उपयोग करने से पहले वैरिएबल की घोषणा नहीं करने के लिए :-)
user2676847

28

जाहिरा तौर पर use strict(जरूरी) का उपयोग किया है जब आप कोड को ठीक से जो घोषणा के लिए मजबूर किया जा सकता है करने के लिए बल पर्ल करना चाहते हैं, तार और बाद के चरणों पर स्पष्ट किया जा रहा barewords यानी या सावधानी के साथ refs का उपयोग कर देना चाहिए। नोट: यदि त्रुटियां हैं, तो सख्ती से उपयोग करने पर निष्पादन समाप्त हो जाएगा।

जब use warnings;आप प्रोग्राम में टाइपिंग की गलतियाँ ढूंढने में मदद करेंगे जैसे कि आप एक अर्धविराम से चूक गए थे, तो आपने 'अन्य' का इस्तेमाल किया था और 'एल्सिफ़' का नहीं, आप डिप्रेक्टेड सिंटैक्स या फ़ंक्शन का उपयोग कर रहे हैं, जो भी ऐसा हो। नोट: चेतावनियों का उपयोग केवल चेतावनी प्रदान करेगा और निष्पादन जारी रखेगा अर्थात निष्पादन को निरस्त न करे ।।

वैसे भी, बेहतर होगा कि हम विवरण में जाएं, जिसे मैं नीचे बता रहा हूं

से perl.com (मेरी पसंदीदा):

सख्त 'vars' का उपयोग करें;

जिसका अर्थ है कि आपको उन्हें उपयोग करने से पहले हमेशा चर घोषित करना चाहिए।

यदि आप घोषित नहीं करते हैं तो आपको शायद अघोषित चर के लिए त्रुटि संदेश मिलेगा

वैश्विक प्रतीक "$ varablename" में scriptname.pl लाइन 3 पर स्पष्ट पैकेज नाम की आवश्यकता होती है

इस चेतावनी का अर्थ है कि पर्ल के बारे में बिल्कुल स्पष्ट नहीं है कि चर का दायरा क्या है। तो आपको अपने चर के बारे में स्पष्ट होने की आवश्यकता है, जिसका अर्थ है कि या तो उन्हें घोषित करना myताकि वे वर्तमान ब्लॉक तक ही सीमित रहें, या उनके पूर्ण योग्य नाम के साथ उनका उल्लेख करें (उदाहरण के लिए: $ MAIN :: varablename)।

यदि आप किसी चर को एक्सेस करने का प्रयास करते हैं तो कंपाइल-टाइम त्रुटि शुरू हो जाती है, जो निम्न मानदंडों में से कम से कम एक को पूरा नहीं करता है:

  • Perl द्वारा पूर्वनिर्धारित, जैसे @ARGV,% ENV और सभी वैश्विक विराम चिह्न जैसे $। या $ _।

  • हमारे (एक वैश्विक के लिए) या मेरे (एक शाब्दिक के लिए) के साथ घोषणा की।

  • दूसरे पैकेज से आयात किया गया। (उपयोग वर्जन प्राग्मा आयात आयात करता है, लेकिन हमारे बजाय इसका उपयोग करें।)

  • पूरी तरह से अपने पैकेज के नाम और डबल-कोलोन पैकेज सेपरेटर का उपयोग करके योग्य है।

सख्त 'उप' का उपयोग करें;

दो कार्यक्रमों पर विचार करें

# prog 1
   $a = test_value;
   print "First program: ", $a, "\n";
   sub test_value { return "test passed"; }
 Output: First program's result: test_value

# prog 2
   sub test_value { return "test passed"; }
   $a = test_value;
   print "Second program: ", $a, "\n";
 Output: Second program's result: test passed

दोनों ही मामलों में हमारे पास एक test_value () उप है और हम इसका परिणाम $ a में डालना चाहते हैं। और फिर भी, जब हम दो प्रोग्राम चलाते हैं, तो हमें दो अलग-अलग परिणाम मिलते हैं:

पहले कार्यक्रम में, हम जिस बिंदु पर $a = test_value;पहुंचते हैं, पर्ल को किसी भी test_value () उप का पता नहीं होता है, और test_value को स्ट्रिंग 'test_value' के रूप में व्याख्या की जाती है। दूसरे प्रोग्राम में, $a = test_value;लाइन से पहले test_value () की परिभाषा आती है । Perl सोचता है कि test_value उप कॉल के रूप में है।

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

बग वह है जो हमने अपने पहले कार्यक्रम में सामना किया था, याद रखें कि पर्ल खोजने के लिए आगे नहीं आएगा test_value(), इसलिए चूंकि यह पहले से ही test_value () नहीं देखा है, इसलिए यह मानता है कि आप एक स्ट्रिंग चाहते हैं। तो अगर तुम use strict subs;, यह एक त्रुटि के साथ मरने के लिए इस कार्यक्रम का कारण होगा:

"सख्त उप" के उपयोग के लिए "%_" पर अनुमति नहीं है।

इस त्रुटि का समाधान
1 होगा । यह स्पष्ट करने के लिए कोष्ठकों का उपयोग करें कि आप उप को कॉल कर रहे हैं। यदि पर्ल $ a = test_value () देखता है, तो
2. पहले अपना उपयोग करने से पहले अपने उप की घोषणा करें

use strict;
sub test_value;  # Declares that there's a test_value() coming later ...
my $a = test_value;  # ...so Perl will know this line is okay.
.......
sub test_value { return "test_passed"; }

3. और यदि आप इसे एक स्ट्रिंग के रूप में उपयोग करने के लिए कहते हैं, तो इसे उद्धृत करें।

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

इस अप्रत्याशित व्यवहार के कारण बेयरस खतरनाक हैं। use strict; (or use strict 'subs';)उन्हें अनुमान लगाने योग्य बनाता है, क्योंकि नंगे पासवर्ड जो भविष्य में अजीब व्यवहार का कारण बन सकते हैं, इससे पहले कि वे कहर बरपा सकें, इससे आपका कार्यक्रम मर जाएगा

वहाँ एक जगह है जहाँ आप सख्त उप-चालू होने पर भी नंगे पासवर्ड का उपयोग करना ठीक है: जब आप हैश कीज़ असाइन कर रहे हैं।

$hash{sample} = 6;   # Same as $hash{'sample'} = 6
%other_hash = ( pie => 'apple' );

हैश कीज़ में बेयरस को हमेशा स्ट्रिंग्स के रूप में व्याख्या किया जाता है, इसलिए कोई अस्पष्टता नहीं है।

सख्त 'रेफ्स' का उपयोग करें;

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

use strict 'refs';

$ref = \$foo;       # Store "real" (hard) reference.
print $$ref;        # Dereferencing is ok.

$ref = "foo";       # Store name of global (package) variable.
print $$ref;        # WRONG, run-time error under strict refs.

चेतावनी का उपयोग करें;

यह लेक्सिकली स्कोप्ड प्राग्मा पर्ल के अंतर्निहित चेतावनियों पर लचीले नियंत्रण की अनुमति देता है, जो संकलक द्वारा उत्सर्जित उन दोनों के साथ-साथ रन-टाइम सिस्टम से भी।

से perldiag:

इसलिए नीचे दिए गए वर्गीकरणों में से अधिकांश चेतावनी संदेशों का अर्थ है कि डब्ल्यू, डी एंड एस को warningsप्रागमा का उपयोग करके नियंत्रित किया जा सकता है ।

(डब्लू) एक चेतावनी (वैकल्पिक)
(डी) एक पदावनत (डिफ़ॉल्ट रूप से सक्षम)
(एस) एक गंभीर चेतावनी (सक्षम)

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

(डब्ल्यू) एक चेतावनी (वैकल्पिक):

% S में
मिसिंग तर्क -% c से मिसिंग तर्क -
(क्या आपका मतलब है और इसके बजाय% s?)
(क्या "हमारा" के बजाय "स्थानीय" का अर्थ है?)
(क्या आप% के बजाय $ या @ का मतलब है?)
'% S '
% s
मिसप्लाज्ड _ पर संख्या में प्रयुक्त कोड संदर्भ लंबाई () नहीं है

(डी) एक वेतन वृद्धि (डिफ़ॉल्ट रूप से सक्षम):

परिभाषित (@array) पदावनत
परिभाषित है (% हैश) पदावनत
है मेरा () गलत डिप्रेस्ड
$ में # का उपयोग अब समर्थित नहीं है

(एस) एक गंभीर चेतावनी (डिफ़ॉल्ट रूप से सक्षम)

ओईनिफ़ को एलीसिफ़
% s मिल जाना चाहिए जहाँ ऑपरेटर को उम्मीद थी
(% s से पहले मिसिंग ऑपरेटर?)
(पिछली पंक्ति पर अर्धविराम की कमी ?)
% s ने कभी भी
ऑपरेटर या अर्धविराम नहीं पेश किया जो % s से पहले गायब हो गया है।
समस्या: खुला% ओपन होना चाहिए (% s)
प्रोटोटाइप बेमेल:% s बनाम% s
चेतावनी: कोष्ठक के बिना "% s" का उपयोग अस्पष्ट है,
% s नहीं खोल सकता:% s


10

ये दो प्रैगमास आपके कोड में स्वचालित रूप से बग की पहचान कर सकते हैं।

मैं हमेशा अपने कोड में इसका उपयोग करता हूं:

use strict;
use warnings FATAL => 'all';

FATALचेतावनियों की तरह कोड को भी मरवा देता strictहै।

अतिरिक्त जानकारी के लिए, देखें: उपयोग चेतावनी के साथ कठोर हो जाओ FATAL => 'all';

इसके अलावा ... सईस के अनुसार, सख्ती


दरअसल, आपको FATAL => "all"रनटाइम तक देरी करनी होती है, $SIG{__WARN__} = sub { croak "fatalized warning @_" };या फिर असाइन करके आप कंपाइलर को यह बताने की कोशिश करते हैं कि आपको इसकी क्या जरूरत है।
23

6
@ टिचर: यह हमेशा मेरे लिए-जैसा और प्रलेखित है। यदि आपको एक ऐसा मामला मिला है जहाँ यह दस्तावेज के रूप में काम नहीं करता है, तो कृपया दस्तावेज़ का उपयोग करके पैच करें perlbug
टूलिक

9

नहीं है perlmonks पर एक अच्छा धागा इस सवाल के बारे।

मूल कारण स्पष्ट रूप से यह है कि सख्त और चेतावनियाँ आपको गलतियों को पकड़ने और डिबगिंग में सहायता करने में मदद करती हैं।


3

स्रोत :: विभिन्न ब्लॉग

मॉड्यूल आयातों () फ़ंक्शन को कॉल करके मुख्य नाम स्थान पर फ़ंक्शन और चर नाम निर्यात करेगा।

प्रागमा एक ऐसा मॉड्यूल है जो संकलित समय के कुछ पहलू को प्रभावित करता है या perl के समय के व्यवहार को प्रभावित करता है। प्रजाम संकलक को संकेत देते हैं।

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

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


1

"उपयोग सख्त" निर्देश अपने कोड के संकलन के दौरान पर्ल को अतिरिक्त जाँच करने के लिए कहता है। इस निर्देश का उपयोग करने से आपको अपने पर्ल कोड को डीबग करने में समय की बचत होगी क्योंकि यह सामान्य कोडिंग बग ढूंढता है जिन्हें आप अन्यथा अनदेखा कर सकते हैं।


0

सख्त और चेतावनी सुनिश्चित करें कि आपके चर वैश्विक नहीं हैं।

यह प्रत्येक और हर नाम चर का ट्रैक रखने के बजाय अलग-अलग तरीकों के लिए अद्वितीय चर रखने में सक्षम होने के लिए बहुत अधिक है।

$ _, या कुछ फ़ंक्शंस के लिए कोई वैरिएबल नहीं, अधिक कॉम्पैक्ट कोड लिखने के लिए भी उपयोगी हो सकता है।

हालांकि, यदि आप सख्त और चेतावनियों का उपयोग नहीं करते हैं, तो $ _ वैश्विक हो जाता है!


0
use strict;
use warnings;

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

चेतावनियों का अर्थ -wपर्ल शेलबैंग लाइन की तरह है, इसलिए यह आपको पर्ल प्रोग्राम द्वारा उत्पन्न चेतावनियां प्रदान करेगा, यहhehe टर्मिनल प्रदर्शित करेगा

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