Gawk: फ़ंक्शन के लिए सरणियाँ पास करना


9

GNU के साथ अटक 3.1.6 और लगता है कि मैंने इसके सरणी बग के आसपास काम किया है, लेकिन अभी भी 600-लाइन awk प्रोग्राम में स्कोप समस्या की तरह दिखता है। मेरी बग को खोजने के लिए awk में सरणी क्षेत्र की समझ को सत्यापित करने की आवश्यकता है।

इस निराशाजनक awk कोड को देखते हुए ...

function foo(ga) {
  ga[1] = "global result"
}

garray[1] = "global"
foo(garray)

print garray[1]

प्रिंट होगा ...

global result

चूँकि सरणियों को हमेशा संदर्भ द्वारा कार्यों के लिए पारित किया जाता है, तो सभी सरणियाँ हमेशा वैश्विक होती हैं। स्थानीय सरणी बनाने का कोई तरीका नहीं है। क्या ये सही है? स्पष्ट रूप से ऐसा कहने वाले डॉक्स नहीं मिल पाए हैं।

जब से मैं डिबगिंग कर रहा हूं, और 3.1.6 ने ही इस क्षेत्र में बग्स को जाना है, मैं यह निर्धारित करने की कोशिश कर रहा हूं कि awk के कीड़े कहां से निकलते हैं और मेरा शुरू होता है।

पूरक: क्यों गै [] कार्य के अंदर काम करता है?

सबसे पहले, सरणी को फ़ंक्शन के साथ पास foo(ga)करना वास्तव में अनावश्यक है। बस इसे garray[]फंक्शन के अंदर एक्सेस करें । हालांकि इसे करने में कोई औसत दर्जे का प्रदर्शन जुर्माना नहीं है, और यह डीबगिंग और त्रुटि रिपोर्टिंग में मदद करता है।

का उपयोग करते हुए foo(ga), ga[]वैश्विक सरणी के लिए एक पर्याय है garray[]। की एक स्थानीय प्रति होने के बजाय garray[], यह केवल एक सूचक है garray[], बल्कि एक प्रतीकात्मक लिंक एक फ़ाइल के लिए एक संकेतक है और इस प्रकार एक ही फ़ाइल (या सरणी) को एक से अधिक नामों के तहत एक्सेस किया जा सकता है।

पूरक: ग्लेन जैकमैन के जवाब का स्पष्टीकरण

जबकि किसी फ़ंक्शन के बाहर बनाई गई सरणियाँ फ़ंक्शन के लिए वैश्विक होती हैं और इसे पास किया जा सकता है या इसके भीतर संदर्भित किया जा सकता है, फ़ंक्शन के अंदर बनाए गए सरणियाँ वास्तव में फ़ंक्शन के लिए स्थानीय रहती हैं और इसके बाहर दिखाई नहीं देती हैं। श्री जैकमैन के उदाहरण को संशोधित करने से यह स्पष्ट होता है ...

awk '
    function bar(x,y) {
      split("hello world", y)
      print "x[1] inside: " x[1]
      print "y[1] inside: " y[1]
    }
    BEGIN {
      x[1]="goodbye"
      print "x[1] before: " x[1]
      print "y[1] before: " y[1]
      bar(x)
      print "x[1] after: " x[1]
      print "y[1] after: " y[1]
    }
'
x[1] before: goodbye
y[1] before: 
x[1] inside: goodbye
y[1] inside: hello
x[1] after: goodbye
y[1] after: 

ध्यान दें कि हम केवल x[]सरणी को पारित कर रहे हैं (वास्तव में, इसके लिए केवल एक संकेतक) bar()y[]सरणी भी मौजूद नहीं है जब तक हम समारोह के अंदर मिलता है।

हालाँकि, अगर हम इसे फ़ंक्शन के बाहर कुछ भी बताए बिना तर्क सूची y[]में शामिल करके घोषित करते हैं, तो bar()यह कॉल करने के बाद दिखाई देता है bar(x,y)...

awk '
    function bar(x,y) {
      split("hello world", y)
      print "x[1] inside: " x[1]
      print "y[1] inside: " y[1]
    }
    BEGIN {
      x[1]="goodbye"
      print "x[1] before: " x[1]
      print "y[1] before: " y[1]
      bar(x,y)
      print "x[1] after: " x[1]
      print "y[1] after: " y[1]
    }
'
x[1] before: goodbye
y[1] before: 
x[1] inside: goodbye
y[1] inside: hello
x[1] after: goodbye
y[1] after: hello

अंत में, यदि हम y[]फ़ंक्शन के बाहर एरे बनाते हैं और इसे पास करते हैं bar(x,y), split()तो फंक्शन के अंदर असाइनमेंट उस एरेन्स एलिमेंट्स को बदल देता है ...

awk '
    function bar(x,y) {
      split("hello world", y)
      print "x[1] inside: " x[1]
      print "y[1] inside: " y[1]
    }
    BEGIN {
      x[1]="goodbye"
      y[1]="howdy"
      print "x[1] before: " x[1]
      print "y[1] before: " y[1]
      bar(x,y)
      print "x[1] after: " x[1]
      print "y[1] after: " y[1]
    }
'
x[1] before: goodbye
y[1] before: howdy
x[1] inside: goodbye
y[1] inside: hello
x[1] after: goodbye
y[1] after: hello

जवाबों:


5

फ़ंक्शन पैरामीटर फ़ंक्शन के लिए स्थानीय हैं।

awk '
    function foo(x,y) {y=x*x; print "y in function: "y} 
    BEGIN {foo(2); print "y out of function: " y}
'
y in function: 4
y out of function: 

यदि आप किसी मानदंड से कम मान पास करते हैं, तो अतिरिक्त मानदंड खाली हैं। आप कभी-कभी ऐसे कार्यों को देख सकते हैं जिन्हें परिभाषित किया गया है

function foo(a, b, c            d, e, f) {...

जहां व्हाट्सएप के बाद पैरामीटर स्थानीय चर होते हैं और आह्वान पर मूल्य लेने का इरादा नहीं होता है।

कोई कारण नहीं कि यह स्थानीय सरणियों के लिए काम नहीं कर सकता:

awk '
    function bar(x) {
        split("hello world", x)
        print "in: " x[1]
    }
    BEGIN {
        x[1]="world"
        bar()
        print "out: " x[1]}
'
in: hello
out: world

3

Gawk प्रलेखन यह स्पष्ट है कि सरणियों संदर्भ द्वारा पारित कर रहे हैं बनाता है, और कोई है कि चारों ओर दस्तावेज़ीकरण किया गया है जिस तरह से। व्यवहार gawk4.0.1 के साथ समान है ।

POSIX उस व्यवहार को निर्दिष्ट करता है , इसलिए मुझे उम्मीद नहीं है कि आप किसी भी awkकार्यान्वयन को पाएंगे जो अन्यथा व्यवहार करता है।

यदि आपको उस कार्यक्षमता की आवश्यकता है, तो आप उपयोग कर सकते हैं perl। स्क्रिप्ट का अनुवाद करने के लिए perlएक उपकरण ( a2p) के साथ आता awkहै perl

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