खोज…
टिप्पणियों
ब्रेडेड एक्सप्रेशन स्ट्रिंग्स का उपयोग करने से एक और लाभ यह है कि बाइट कंपाइलर आमतौर पर उनसे अधिक कुशल कोड (5 - 10x तेज) उत्पन्न कर सकता है।
असंबंधित अभिव्यक्तियों के साथ समस्याएं
लटके तार के रूप में अभिव्यक्ति स्ट्रिंग तर्क प्रदान करने के लिए यह एक अच्छा अभ्यास है। शीर्षक "डबल प्रतिस्थापन" उसी के पीछे महत्वपूर्ण कारणों को रेखांकित करता है।
एक मूल्य की गणना करने के लिए expr कमांड एक ऑपरेटर-आधारित अभिव्यक्ति स्ट्रिंग का मूल्यांकन करता है। इस तार का निर्माण आह्वान में तर्कों से किया गया है।
expr 1 + 2 ; # three arguments
expr "1 + 2" ; # one argument
expr {1 + 2} ; # one argument
ये तीन आह्वान समकक्ष हैं और अभिव्यक्ति स्ट्रिंग समान है।
आदेश, if , के for , और while उनके हालत तर्क के लिए एक ही मूल्यांकनकर्ता कोड का उपयोग करें:
if {$x > 0} ...
for ... {$x > 0} ... ...
while {$x > 0} ...
मुख्य अंतर यह है कि स्थिति अभिव्यक्ति स्ट्रिंग को हमेशा एक ही तर्क होना चाहिए।
Tcl में एक आदेश आह्वान में हर तर्क के साथ, सामग्री को प्रतिस्थापन के अधीन नहीं किया जा सकता है या नहीं, इस आधार पर कि वे कैसे उद्धृत / बच गए हैं:
set a 1
set b 2
expr $a + $b ; # expression string is {1 + 2}
expr "$a + $b" ; # expression string is {1 + 2}
expr \$a + \$b ; # expression string is {$a + $b}
expr {$a + $b} ; # expression string is {$a + $b}
तीसरे और चौथे मामलों में अंतर है क्योंकि बैकस्लैश / ब्रेसेस प्रतिस्थापन को रोकते हैं। परिणाम अभी भी वही है, क्योंकि expr अंदर मूल्यांकनकर्ता स्वयं Tcl चर प्रतिस्थापन कर सकता है और स्ट्रिंग को {1 + 2} ।
set a 1
set b "+ 2"
expr $a $b ; # expression string is {1 + 2}
expr "$a $b" ; # expression string is {1 + 2}
expr {$a $b} ; # expression string is {$a $b}: FAIL!
यहाँ हम braced तर्क के साथ मुसीबत में: जब में मूल्यांकनकर्ता expr प्रदर्शन प्रतिस्थापन, अभिव्यक्ति स्ट्रिंग पहले से ही ऑपरेटरों और ऑपरेंड में पार्स कर दिया गया है, तो क्या मूल्यांकनकर्ता देखता है उनके बीच कोई ऑपरेटर के साथ दो ऑपरेंड से मिलकर एक श्रृंखला है। (त्रुटि संदेश " missing operator at _@_ in expression "$a _@_$b" " है।)
इस स्थिति में, expr से पहले परिवर्तनीय प्रतिस्थापन को एक त्रुटि को रोकने के लिए कहा गया था। तर्क का अनुमान लगाने से अभिव्यक्ति के मूल्यांकन तक परिवर्तनीय प्रतिस्थापन को रोक दिया गया, जिससे त्रुटि हुई।
इस तरह की स्थिति तब हो सकती है, जब आमतौर पर मूल्यांकन करने के लिए एक अभिव्यक्ति को एक चर या पैरामीटर के रूप में पारित किया जाता है। उन मामलों में वहाँ कोई अन्य विकल्प तर्क को प्रसव के लिए "खोल" अभिव्यक्ति स्ट्रिंग के लिए तर्क मूल्यांकनकर्ता अनुमति देने के लिए unbraced छोड़ने के लिए की तुलना में है expr ।
अधिकांश अन्य मामलों में, हालांकि, अभिव्यक्ति को भंग करने से कोई नुकसान नहीं होता है और वास्तव में बहुत सारी समस्याओं को हल किया जा सकता है। इसके कुछ उदाहरण:
डबल प्रतिस्थापन
set a {[exec make computer go boom]}
expr $a ; # expression string is {[exec make computer go boom]}
expr {$a} ; # expression string is {$a}
अनबॉर्म्ड फॉर्म कमांड प्रतिस्थापन का प्रदर्शन करेगा, जो कि एक कमांड है जो कंप्यूटर को किसी भी तरह से नष्ट कर देता है (या हार्ड डिस्क को एन्क्रिप्ट या प्रारूपित करता है, या आपके पास क्या है)। लट रूप एक चर प्रतिस्थापन का प्रदर्शन करेगा और फिर स्ट्रिंग के कुछ बनाने के लिए (और विफल) "[कंप्यूटर को निष्पादित करें बूम]" निष्पादित करें। आपदा टल गई।
अंतहीन छोरों
set i 10
while "$i > 0" {puts [incr i -1]}
यह समस्या while और while दोनों के for प्रभावित करती है। हालांकि ऐसा लगता है कि यह लूप 0 से नीचे गिना जाएगा और बाहर निकल जाएगा, जबकि वास्तव में तर्क हमेशा 10>0 क्योंकि तर्क का मूल्यांकन किया गया था while कमांड को सक्रिय किया गया था। जब तर्क braced है, यह करने के लिए पारित कर दिया है while के रूप में आदेश $i>0 , और चर हर यात्रा के लिए एक बार प्रतिस्थापित किया जाएगा। इसके बजाय इसका उपयोग करें:
while {$i > 0} {puts [incr i -1]}
कुल मूल्यांकन
set a 1
if "$a == 0 && [incr a]" {puts abc}
का मूल्य क्या है a इस कोड को चलाने के बाद? चूंकि && ऑपरेटर केवल सही ऑपरेंड का मूल्यांकन करता है यदि बाएं ऑपरेंड सही है, तो मान अभी भी 1 होना चाहिए। लेकिन वास्तव में, यह 2 है। ऐसा इसलिए है क्योंकि तर्क मूल्यांकनकर्ता ने पहले ही सभी चर और कमांड सबस्टेशन का प्रदर्शन किया है जब तक अभिव्यक्ति स्ट्रिंग है। का मूल्यांकन किया। इसके बजाय इसका उपयोग करें:
if {$a == 0 && [incr a]} {puts abc}
कई ऑपरेटरों (तार्किक संयोजक || && , और सशर्त ऑपरेटर ?: :) को उनके सभी ऑपरेंडों का मूल्यांकन नहीं करने के लिए परिभाषित किया गया है, लेकिन वे केवल तभी काम कर सकते हैं जब अभिव्यक्ति स्ट्रिंग लट में हो।
एक चर को 17 से गुणा करना
set myVariable [expr { $myVariable * 17 }]
यह दिखाता है कि आप एक चर को अद्यतन करने के लिए एक सरल अभिव्यक्ति का उपयोग कैसे कर सकते हैं। expr कमांड आपके लिए वैरिएबल को अपडेट नहीं करता है; आपको इसका परिणाम लेने की जरूरत है और इसे चर के साथ set लिखें।
ध्यान दें कि expr द्वारा समझी जाने वाली छोटी भाषा में newlines महत्वपूर्ण नहीं हैं, और उन्हें जोड़ने से पढ़ने में अधिक समय तक अभिव्यक्ति हो सकती है।
set myVariable [expr {
$myVariable * 17
}]
हालांकि यह बिल्कुल वैसा ही है।
एक अभिव्यक्ति से Tcl कमांड को कॉल करना
कभी-कभी आपको अपनी अभिव्यक्ति से एक Tcl कमांड को कॉल करने की आवश्यकता होती है। उदाहरण के लिए, मान लें कि आपको इसमें एक स्ट्रिंग की लंबाई की आवश्यकता है। ऐसा करने के लिए, आप अभिव्यक्ति में एक [...] अनुक्रम का उपयोग करते हैं:
set halfTheStringLength [expr { [string length $theString] / 2 }]
आप इस तरह से किसी भी Tcl कमांड को कॉल कर सकते हैं, लेकिन यदि आप खुद को expr कॉलिंग पाते हैं, तो expr ! और सोचें कि क्या आपको वास्तव में उस अतिरिक्त कॉल की आवश्यकता है। आप आमतौर पर कोष्ठक में आंतरिक अभिव्यक्ति डालकर ठीक कर सकते हैं।
अवैध नंगेपन की त्रुटि
Tcl में, एक एकल शब्द से युक्त एक स्ट्रिंग को उद्धृत करने की आवश्यकता नहीं है। अभिव्यक्ति स्ट्रिंग की भाषा में expr मूल्यांकन करता है, सभी ऑपरेंड एक पहचान प्रकार होना चाहिए।
न्यूमेरिक ऑपरेशंस बिना किसी सजावट के लिखे गए हैं:
expr {455682 / 1.96e4}
तो बूलियन स्थिरांक हैं:
expr {true && !false}
Tcl चर प्रतिस्थापन सिंटैक्स पहचाना जाता है: ऑपरेंड को चर के मान पर सेट किया जाएगा:
expr {2 * $alpha}
वही कमांड प्रतिस्थापन के लिए जाता है:
expr {[llength $alpha] > 0}
कोष्ठक के भीतर परिचालनों की अल्पविराम से अलग सूची के साथ ऑपरेंड गणितीय फ़ंक्शन कॉल भी हो सकते हैं:
expr {sin($alpha)}
एक ऑपरेंड एक डबल-उद्धृत या लट में स्ट्रिंग हो सकता है। एक कमांड लाइन की तरह एक डबल-कोटेड स्ट्रिंग प्रतिस्थापन के अधीन होगा।
expr {"abc" < {def}}
यदि कोई ऑपरेंड उपरोक्त में से एक नहीं है, तो यह अवैध है। चूंकि कोई संकेत नहीं है जो दिखाता है कि यह किस तरह का शब्द है, expr एक नंगे तलवार त्रुटि का संकेत देता है।