perl - फाईलहाण्डल और लूप के साथ परिभाषित की उपयोग




while-loop filehandle (2)

कहें कि आपके पास निम्न फाइल है

4<LF>
3<LF>
2<LF>
1<LF>
0

( <LF> एक लाइन फ़ीड को दर्शाता है। ध्यान दें कि अंतिम पंक्ति पर नई पंक्ति की कमी है।)

कहो आप कोड का उपयोग करें

while ($s = <>) {
   chomp;
   say $s;
}

अगर पर्ल कुछ भी जादुई नहीं था, तो उत्पादन होगा

4
3
2
1

0 की कमी ध्यान दें, क्योंकि स्ट्रिंग 0 झूठी है। defined की संभावना नहीं है की संभावना नहीं है कि मामले में

  • आपके पास एक गैर-मानक पाठ फ़ाइल है (नई लाइन को पीछे छोड़ना)
  • फ़ाइल की अंतिम पंक्ति में एक एकल एएससीआईआई शून्य (0x30) होता है।

लेकिन एक मिनट इंतजार! यदि आप उपर्युक्त आंकड़ों के साथ उपर्युक्त कोड चलाते हैं, तो आपको 0 प्रिंट होगा! कई लोग नहीं जानते कि पर्ल स्वचालित रूप से अनुवादित है

while ($s = <>) {

सेवा मेरे

while (define($s = <>)) {

जैसा कि यहां देखा गया है:

$ perl -MO=Deparse -e'while($s=<DATA>) {}'
while (defined($s = <DATA>)) {
    ();
}
__DATA__
-e syntax OK

इसलिए आपको तकनीकी defined से इस बहुत विशिष्ट परिस्थिति में defined करने की आवश्यकता भी नहीं है।

उस ने कहा, मैं पर्ल पर निर्भर होने के बजाय किसी के लिए स्पष्ट रूप से दोषी नहीं ठहरा सकता, स्वचालित रूप से अपने कोड को संशोधित करता है। सब के बाद, पर्ल (जरूरी) काफी विशिष्ट है क्योंकि यह कोड अनुक्रम जो बदल जाएगा। निम्न में defined की कमी नोट हालांकि यह माना जाता है कि समकक्ष कोड है:

$ perl -MO=Deparse -e'while((), $s=<DATA>) {}'
while ((), $s = <DATA>) {
    ();
}
__DATA__
-e syntax OK

उन्नत पर्ल प्रोग्रामिंग [1] पर एक किताब पढ़ते समय, मैं इस कोड पर आया था:

while (defined($s = <>)) {
    ...

यहां defined करने के लिए कोई विशेष कारण है? Perlop के लिए प्रलेख का कहना है:

इन लूप निर्माणों में, असाइन किए गए मूल्य (चाहे असाइनमेंट स्वचालित या स्पष्ट है) तब जांचने के लिए जांच की जाती है कि क्या यह परिभाषित है या नहीं। परिभाषित परीक्षण समस्या से बचा जाता है जहां पंक्ति में एक स्ट्रिंग मान होता है जिसे पर्ल द्वारा गलत मानता है, उदाहरण के लिए कोई "" या "0" कोई पिछली नई लाइन के साथ नहीं। यदि आप वास्तव में ऐसे मानों के लिए पाश को समाप्त करना चाहते हैं, तो उन्हें स्पष्ट रूप से जांचना चाहिए: [...]

इसलिए, एक कोने के मामले होंगे या यह सिर्फ इसलिए कि किताब बहुत पुरानी है और स्वचालित defined परीक्षण हाल ही में एक पर्ल संस्करण में जोड़ा गया था?

[1] उन्नत पर्ल प्रोग्रामिंग, प्रथम संस्करण, श्रीराम श्रीनिवासन ओ रेली (1 99 7)


पर्ल के बहुत सारे निहित व्यवहार हैं, अधिकांश अन्य भाषाओं की तुलना में बहुत अधिक हैं पर्ल का आदर्श वाक्य है कि यह करने के लिए एक से भी अधिक है, और क्योंकि ऐसा बहुत अनैतिक व्यवहार है, वही तरीका एक ही तरह से व्यक्त करने के लिए अक्सर एक से अधिक है

/foo/ $_ =~ m/foo/ बजाय $_ =~ m/foo/

$x = shift बजाय $x = shift @_

while (defined($_=<ARGV>)) बजाय while (defined($_=<ARGV>)) while(<>)

आदि।

उपयोग करने के लिए कौन से भाव काफी हद तक आपके स्थानीय कोडिंग मानकों और निजी प्राथमिकता के मामले हैं। अधिक स्पष्ट अभिव्यक्ति पाठक को याद दिलाता है कि वास्तव में हुड के नीचे क्या चल रहा है यह कोड की पठनीयता में सुधार या सुधार नहीं सकता है - यह निर्भर करता है कि दर्शक कितना ज्ञानी है और क्या आप प्रसिद्ध मुहावरों का उपयोग कर रहे हैं।

इस मामले में, निहित व्यवहार ऐसा लगता है जितना अधिक जटिल होता है। कभी-कभी perl रीडलाइन ऑपरेटर के परिणाम पर एक defined(...) परीक्षण निष्पादित करेगा:

$ perl -MO=Deparse -e 'while($s=<>) { print $s }'
while (defined($s = <ARGV>)) {
    print $s;
}
-e syntax OK

लेकिन कभी-कभी यह नहीं होगा:

$ perl -MO=Deparse -e 'if($s=<>) { print $s }'
if ($s = <ARGV>) {
    print $s;
}
-e syntax OK

$ perl -MO=Deparse -e 'while(some_condition() && ($s=<>)) { print $s }'
while (some_condition() and $s = <ARGV>) {
    print $s;
}
-e syntax OK

मान लीजिए कि आप कोने के मामलों के बारे में चिंतित हैं, जो इस निहित व्यवहार को संभालना चाहते हैं। क्या आपने मेमोरी को perlop किया है ताकि आप समझ सकें कि जब पर्ल इस अंतर्निहित व्यवहार का उपयोग करता है और जब ऐसा नहीं होता है? क्या आप पर्ल v5.14 और पर्ल v5.6 के बीच इस व्यवहार में अंतर को समझते हैं? क्या आपके कोड को पढ़ने वाले लोग समझेंगे?

दोबारा, अधिक स्पष्ट अभिव्यक्ति का उपयोग करने के बारे में कोई सही या गलत जवाब नहीं है, लेकिन स्पष्ट अभिव्यक्ति का उपयोग करने का मामला मजबूत होता है जब अंतर्निहित व्यवहार अधिक गूढ़ होता है







filehandle