2010-08-09 7 views
8

में मैं "शुरुआत पर्ल" पुस्तक पढ़ रहा हूँ, और यह इन दो बयानों देता है:सूची ऑपरेटर पूर्वता पर्ल

print "Test one: ", 6 > 3 && 3 > 4, "\n"; 
print "Test two: ", 6 > 3 and 3 > 4, "\n"; 

पहली पंक्ति एक नई लाइन के साथ कुछ भी नहीं प्रिंट, दूसरी पंक्ति प्रिंट एक 1 के साथ कोई नई लाइन नहीं

मैं आउटपुट के बारे में उलझन में हूं।

print ("Test two: ", 6 > 3) and 3 > 4, "\n"; 

हालांकि, क्यों पहले बयान नहीं एक ही है: लेखक के अनुसार, दूसरा बयान कह की तरह क्योंकि यह अजीब उत्पादन देता है? मैंने सोचा कि प्रिंट की प्राथमिकता के साथ इसका कुछ संबंध था। & & प्रिंट की तुलना में अधिक प्राथमिकता है, इसलिए इसका मूल्यांकन पहले किया जाता है और फिर इसे मुद्रित किया जाता है। जबकि "और" प्रिंट की तुलना में कम प्राथमिकता है, इसलिए 6> 3 मुद्रित किए जाएंगे, प्रिंट 1 को रिटर्न करेगा, और फिर इसका मूल्यांकन "और" के साथ किया जाएगा। हालांकि यह वास्तव में समझ में नहीं आता है।

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


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

+0

यह कोड चेतावनी प्रिंट करता है। और डेवेल :: REPL – xenoterracide

+0

@xenoterracide में भी मज़ेदार व्यवहार है, यह अच्छा पर्ल कोड होने का इरादा नहीं है। यह सिर्फ यह वर्णन करने की कोशिश कर रहा है कि प्राथमिकता कैसे काम करती है। – cjm

+0

@cjm दाएं ... हालांकि re.pl का व्यवहार मेरे लिए एक बग दर्ज करने के लिए पर्याप्त गलत लग रहा था। हम देखेंगे कि इसमें क्या आता है। – xenoterracide

उत्तर

12

ठीक है, स्टार्टर्स के लिए: सूची-ऑपरेटर पेर्ल में सबसे कम प्राथमिकता वाली चीज़ों में से हैं, लेकिन केवल उनके दाहिने तरफ पर हैं। आप पूछते हैं इसका क्या अर्थ है: अच्छा, चलिए इसे सरल बनाते हैं। मान लीजिए कि foo नामक एक सूची है। इससे कोई फर्क नहीं पड़ता कि यह क्या करता है, लेकिन यह वहां है। आप sub foo { map 10 * $_, @_ } के साथ आसानी से ऐसी चीज बना सकते हैं जो इसके प्रत्येक तर्क को दस से गुणा करता है। इस तरह से बाहर:

print 1, 2, 3;print(1, 2, 3);
print foo 1, 2, 3; के बराबर है print(foo(1, 2, 3));
print 1, foo 2, 3; के बराबर है हम देख सकते हैं कि foo यह कर सकते हैं के रूप में सही पक्ष पर के रूप में ज्यादा ऊपर gobbles print(1, foo(2, 3));

के बराबर है - केवल कथन का अंत (अब तक ...) इसे रोक सकता है। अगर हमने @array = (1, foo 2, 3); लिखा है जो @array = (1, foo(2, 3)); के बराबर होगा क्योंकि निश्चित रूप से आसपास के कोष्ठक समाप्त होने पर भी लागू होता है।

चूंकि अल्पविराम भी बहुत कम प्राथमिकता है (केवल "सूची ऑपरेटर (दाएं)" से ऊपर), हम किसी भी प्रकार की अभिव्यक्ति को भी एक सूची में तर्क में रखना चाहते हैं - यह केवल सुनिश्चित करने का तरीका है कि हमें ज्यादातर समय कोष्ठक जोड़ने की ज़रूरत नहीं है। गणित, bitwise ऑपरेटरों, तुलना, यहां तक ​​कि regex मैचों की उच्च प्राथमिकता है।

केवल चीजें हैं जो कम प्राथमिकता है वर्तनी-आउट तार्किक संयोजियों and, or, xor, और not हैं। तो अगर हम

foo 1, 2, 3 and 4; 

कि (foo(1, 2, 3) and 4) मतलब है लिखने - and के बाईं ओर तर्क foo स्टॉप के लिए।यह एक काल्पनिक उदाहरण में मूर्खतापूर्ण लगता है, तो चलो यह एक आम पर्ल मुहावरा में बदल जाते हैं करते हैं:

open $fh, '<', $filename or die "$! opening $filename"; 

जो

(open($fh, '<', $filename) or die("$! opening $filename")); 

के बराबर है जो वास्तव में करने के लिए बिल्कुल बराबर है (और करने के लिए संकलित)

die "$! opening $filename" unless open $fh, '<', $filename; 

unless के कथन-संशोधक रूप का उपयोग करके (जो एक ऑपरेटर नहीं है, केवल प्रति कथन केवल एक बार अनुमति है, और केवल एक कथन के अंत में आता है, इसलिए यह ' वास्तव में प्राथमिकता में संलग्न नहीं है, लेकिन आप इसे "निम्नतम से कम" प्राथमिकता के रूप में मान सकते हैं)।

तो वैसे भी, अपने मूल कोड नमूना की ओर लौटने - print अंत सिर्फ and की बाईं करने के लिए तर्क है, और and के अधिकार के लिए एक पूरी तरह से अलग अल्पविराम अभिव्यक्ति है - जो कुछ भी नहीं करता है यह बस कुछ ही है, क्योंकि स्थिरांक में स्थिरांक 3 > 4 और "\n" मूल्यांकन किया गया।

+1

++: तारकीय स्पष्टीकरण! – Zaid

8

यहाँ उन बयानों पूर्ण कोष्ठकों के साथ यह कैसी दिखाई देगी:

print("Test one: ", ((6 > 3) && (3 > 4)), "\n"); 
print("Test two: ", (6 > 3)) and ((3 > 4), "\n"); 

> सर्वोच्च प्राथमिकता है, तो &&, तो ,, तो print, तो and है।

6 > 31 का मूल्यांकन करता है। 3 > 4 झूठे का मूल्यांकन करता है, जो पर्ल में एक विशेष मान है जो संख्यात्मक संदर्भ में 0 है लेकिन एक स्ट्रिंग संदर्भ में खाली स्ट्रिंग (जैसे यहां)। तो ((6 > 3) && (3 > 4)) खाली स्ट्रिंग उत्पन्न करता है।

इस प्रकार, पहला कथन 0 तर्कों को print: "Test one: ", खाली स्ट्रिंग और एक नई पंक्ति में पास करता है। यह क्रम में प्रत्येक तर्क मुद्रित करता है।

दूसरा कथन print: "Test two: " और 1 पर केवल 2 तर्क पास करता है। नई लाइन मुद्रित नहीं होती है क्योंकि यह print तक कभी नहीं पारित हुई है।

मुझे यकीन नहीं है कि the docs से बेहतर "बाएंवर्ड" और "दाएं" को कैसे समझाया जाए। लेकिन शायद आपको भ्रमित करने वाला यह है कि आप सोच रहे हैं कि "बाएंवर्ड सूची ऑप्स" और "दाएं सूची सूची" हैं। इसका मतलब यह नहीं है। यह कहने की कोशिश कर रहा है कि एक सूची ऑपरेटर के दाईं ओर सबकुछ उस ऑपरेटर के लिए तर्क के रूप में व्याख्या किया जाता है (जब तक आप and जैसे बहुत कम प्राथमिकता वाले बुलीयन ऑपरेटरों में से एक को हिट नहीं करते)। लेकिन एक सूची ऑपरेटर के बाईं ओर की चीजें उस सूची ऑपरेटर से जुड़ी नहीं हैं।

+0

@ हॉब्स: यह किस तरह से सही नहीं है? musikk और मैंने वही बात कहा, सिवाय इसके कि मैंने कुछ अतिरिक्त माता-पिता का उपयोग किया (और अब उनका वापस लेने का दावा है कि '3> 4'' undef' है)। 'Perl-mO = Deparse, -p' का आउटपुट मूल कथन के लिए समान है जो मेरे पूर्ण-संश्लेषित संस्करण बनाम है। – cjm

+0

मुझे खेद है, ऐसा लगता है कि मैं गलत पढ़ता हूं। – hobbs

+0

यह फ़ाइल परीक्षण ऑपरेटरों के मामले में कैसे काम करता है? उदाहरण के लिए, ['टेस्ट :: मोर'] का उपयोग करके (https://metacpan.org/pod/Test:: अधिक) मैंने यह परीक्षण लिखा है 'ठीक है (नहीं $ fn,' फ़ाइल मौजूद नहीं है ')' जो मुझे अपेक्षित के विपरीत करता है .. –

4

जैसा कि आप कहते हैं, "यह समझ में नहीं आता" भाग को छोड़कर यह कहता है।

पहले

print "Test one: ", (6 > 3 && 3 > 4), "\n"; 

और दूसरा

(print "Test two: ", 6 > 3) and (3 > 4, "\n"); 

है, तो आप चेतावनी पर बारी (use warnings) आप चेतावनी Useless use of a constant in void context मिलता है क्योंकि and के दाईं ओर तत्वों के साथ एक सूची का मूल्यांकन झूठी और एक नई लाइन लेकिन कभी भी इसका उपयोग नहीं किया जाता है।

संपादित: सही मेरी दावा undef 3> 4 है। झूठा नहीं है। यह परिभाषित और प्रिंट कुछ भी नहीं है।