2011-08-05 15 views
5

मैं कमांड लाइन से इस एक लाइनर चल रहा हूँ:पर्ल एक मूल्य मुद्रित क्यों करता है जो मुझे वृद्धि के बाद उम्मीद नहीं करता है?

perl -MList::Util=sum -E 'my $x = 0; say sum(++$x, ++$x)' 

यह "4" बजाय "3" क्यों कहता है?

+0

यह भी देखें [क्या पर्ल कोड नमूने अपरिभाषित व्यवहार का कारण बन सकते हैं?] (Http://stackoverflow.com/questions/2176453/what-perl-code-samples-can-lead-to-undefined-behaviour) –

उत्तर

4

आप एक ही कथन में $x दो बार संशोधित कर रहे हैं। docs के अनुसार, पर्ल गारंटी नहीं देगा कि इस कथन का नतीजा क्या है। तो यह "2" या "0" हो सकता है।

+0

दस्तावेज़ों में पारगमन प्रासंगिक नहीं है। यह कहता है कि परिणाम परिभाषित नहीं किया गया है क्योंकि ऑपरेटर के ऑपरेंड मूल्यांकन आदेश को परिभाषित नहीं किया गया है। हालांकि यह '+' (उदाहरण में उपयोग किया गया) के लिए सच है, यह अल्पविराम ऑपरेटर (ओपी द्वारा उपयोग किया जाता है) के लिए नहीं है। अल्पविराम ऑपरेटर का एलएचएस * आरएचएस से पहले मूल्यांकन किया जाने वाला दस्तावेज है। – ikegami

+0

आपको याद है, पर्ल इस मामले में परिणाम की गारंटी नहीं देता है, लेकिन यह एक अलग कारण के लिए है। परिणाम जानना यह जानने पर निर्भर करता है कि क्या पूर्व-वृद्धि मूल (अब संशोधित) स्केलर, या इसकी प्रतिलिपि लौटाती है, और * वह * दस्तावेज नहीं है। (यह पूर्व है, fyi।) – ikegami

3

क्योंकि योग की गणना से पहले दोनों वृद्धिकर्ताओं को निष्पादित किया जाता है।

निष्पादन के बाद, x = 2

2 + 2 = 4. 
+1

यदि यही कारण था, फिर 'योग (++ $ x, ++ $ x)' और 'योग (0 + ++ $ x, 0 + ++ $ x) 'वही परिणाम देगा। – ikegami

+1

@ikegami सत्य नहीं है, क्योंकि अभिव्यक्ति '++ $ x' में एक लाभा प्रकृति है लेकिन अभिव्यक्ति' 0 + ++ $ x' में एक रैल्यू प्रकृति है। आम तौर पर यह अप्रासंगिक है क्योंकि इन्हें रावल के रूप में उपयोग किया जा रहा है, लेकिन अपरिभाषित मामले में जहां आप फ़ंक्शन कॉल के अंदर दो प्रीइन्क्रैक्टमेंट करते हैं, ऐसा लगता है कि प्रारंभिक बनाम-बाध्य-आइश प्रभाव होता है। – hobbs

+0

@ हॉब्स, आप कहते हैं कि मैंने जो कहा वह सच नहीं है, फिर भी आप मेरे बिंदु से सहमत हैं कि सेशन की लालसा प्रकृति वास्तविक कारण है। यह मेरे जवाब में विस्तार से कवर किया गया है। – ikegami

7

सबसे पहले, ध्यान रखें कि पर्ल संदर्भ से गुजरता है। इसका मतलब है कि

sum(++$x, ++$x) 

मूल रूप से के रूप में

do { 
    local @_; 
    alias $_[0] = ++$x; 
    alias $_[1] = ++$x; 
    ∑ 
} 

पूर्व वेतन वृद्धि में ही है चर ही रिटर्न के रूप में यह की एक प्रति * करने का विरोध किया है, तो इसका मतलब है कि $_[0] और $_[1] दोनों $x को एलियास की गई हैं। इसलिए, sum दोनों तर्कों के लिए $x (2) का वर्तमान मान देखता है।

अंगूठे का नियम: एक ही कथन में एक मूल्य को संशोधित और पढ़ना न करें।

* — यह दस्तावेज नहीं है, लेकिन आप पूछ रहे हैं कि पर्ल इस तरह से व्यवहार क्यों कर रहा है।

+0

+1 मुझे लगता है कि आप "$ x' (2) का वर्तमान मान "टाइप करना चाहते हैं। – FMc

+0

@ एफएमसी, धन्यवाद, तय। – ikegami

संबंधित मुद्दे