regex बैकटीक परिणाम पर जबकि() में ग्लोबल रेगेक्स मैच



perl (1)

जिस स्थान पर //g छोड़ दिया गया है वह जादू में संग्रहीत किया जाता है जो उस स्केलर में जोड़ा जाता है, जिस पर मिलान किया जाता था।

$ perl -MDevel::Peek -e'$_ = "abc"; Dump($_); /./g; Dump($_);'
SV = PV(0x32169a0) at 0x3253ee0
  REFCNT = 1
  FLAGS = (POK,IsCOW,pPOK)
  PV = 0x323bae0 "abc"\0
  CUR = 3
  LEN = 10
  COW_REFCNT = 1
SV = PVMG(0x326c040) at 0x3253ee0
  REFCNT = 1
  FLAGS = (SMG,POK,IsCOW,pPOK)
  IV = 0
  NV = 0
  PV = 0x323bae0 "abc"\0
  CUR = 3
  LEN = 10
  COW_REFCNT = 2
  MAGIC = 0x323d050
    MG_VIRTUAL = &PL_vtbl_mglob
    MG_TYPE = PERL_MAGIC_regex_global(g)
    MG_FLAGS = 0x40
      BYTES
    MG_LEN = 1

इसका मतलब यह है कि जिस तरह से व्यवहार किया गया है, उसी तरह बैटिक्स उदाहरण में संभव है यदि मैच ऑपरेटर एक ही स्केलर के साथ मिलान किया गया तो इसका मूल्यांकन चार बार किया गया था! वो कैसे संभव है? ऐसा इसलिए है क्योंकि बैकटीक्स ऑपरेटरों में से एक है जो एक टैग का उपयोग करता है

एक स्केलर बनाना अपेक्षाकृत महंगे है क्योंकि इसमें तीन स्मृति आवंटन की आवश्यकता होती है! प्रदर्शन को बढ़ाने के लिए, टार्का नामक एक स्केलर कुछ ऑपरेटरों के प्रत्येक उदाहरण से जुड़ा हुआ है। जब एक ट्रैक्टर के साथ एक ऑपरेटर का मूल्यांकन किया जाता है, तो वह वापसी के लिए और वापस लौटने के लिए TARG को मूल्य के साथ टैग (एक नए को आबंटित करने और वापस करने के बजाय) भर सकता है।

"तो क्या?", आप पूछ सकते हैं सब के बाद, आप पहले से ही दिखाया है कि एक स्केलर को निर्दिष्ट करना उस स्केलर से जुड़े मैच की स्थिति को रीसेट करता है ऐसा होने का अनुमान है, लेकिन यह बैकल्टी के लिए नहीं है

जादू न केवल जानकारी को एक चर के साथ संलग्न करने की अनुमति देता है, यह कुछ शर्तों के तहत बुलाया जाने वाले कार्यों को भी जोड़ता है। //g द्वारा जोड़ा जाने वाला जादू एक फ़ंक्शन को जोड़ता है जिसे स्केलर संशोधित किए जाने के बाद कहा जाना चाहिए (जो उपरोक्त डंप में SMG ध्वज द्वारा दर्शाया गया है)। यह कार्य वह स्थिति है जो उस स्थिति को साफ़ करता है जब एक मान स्केलर को सौंपा जाता है।

असाइनमेंट ऑपरेटर जादू को ठीक से व्यवस्थित करता है, लेकिन बैकटीक्स ऑपरेटर द्वारा नहीं। यह उम्मीद नहीं करता है कि जादू को अपने टैंक में जोड़ दिया गया है, इसलिए यह जांच नहीं करता कि क्या कोई है, इसलिए मैच की स्थिति साफ़ करने वाला फ़ंक्शन अनारक्षित हो जाता है

यह स्क्रिप्ट शब्द के साथ लाइनों की खोज करता है और उन्हें प्रिंट करता है, जबकि प्रत्येक पुनरावृत्त में स्रोत फ़ाइल को पढ़ना :

# cat mm.pl
#!/usr/bin/perl
use strict;
use warnings;

while( `cat aa` =~ /(\w+)/g ) {
    print "$1\n";
}

इनपुट फ़ाइल:

# cat aa
aa
bb
cc

परिणाम:

# ./mm.pl
aa
bb
cc

कृपया मुझे समझाएं कि स्क्रिप्ट चलाना क्यों नहीं अंतहीन है

हर समय पुनरावृत्त इंजन के लिए ऑफसेट रीसेट किया जाना चाहिए क्योंकि अभिव्यक्ति बदल गई है (नई बिल्ली काढ़ा है)।

मैंने सोचा कि पर्ल बिल्ली के परिणाम के लिए किसी तरह की कैशिंग करता है, लेकिन सीढ़ी के दावों का कारण बनता है कि बिल्ली 4 गुना (3 3 से 3 पंक्तियों के लिए झूठ के लिए 1 शर्त जबकि):

# strace -f ./mm.pl 2>&1 | grep cat | grep -v ENOENT
[pid 22604] execve("/bin/cat", ["cat", "aa"], [/* 24 vars */] <unfinished ...>
[pid 22605] execve("/bin/cat", ["cat", "aa"], [/* 24 vars */] <unfinished ...>
[pid 22606] execve("/bin/cat", ["cat", "aa"], [/* 24 vars */] <unfinished ...>
[pid 22607] execve("/bin/cat", ["cat", "aa"], [/* 24 vars */] <unfinished ...>

दूसरी ओर, निम्नलिखित उदाहरण हमेशा चलता रहता है :

# cat kk.pl
#!/usr/bin/perl
use strict;
use warnings;

my $d = 'aaa';
while( $d =~ /(\w+)/g ) {
    print "$1\n";
    $d = 'aaa';
}

दो स्क्रिप्ट के बीच अंतर कहाँ है? मैं क्या खो रहा हूँ?





perl