perl - Global regex match in while() on backtick result -
this script searches lines words , prints them, while rereading source file in each iteration:
# cat mm.pl #!/usr/bin/perl use strict; use warnings; while( `cat aa` =~ /(\w+)/g ) { print "$1\n"; } input file:
# cat aa aa bb cc result:
# ./mm.pl aa bb cc please explain me why running script isn't endless.
in every while iteration offset regex engine should reset because expression changed (new cat forked).
i thought perl kind of caching cat result, strace claims cat spawned 4 times (3 3 lines + 1 false while condition):
# 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 ...> on other hand, following example runs forever:
# cat kk.pl #!/usr/bin/perl use strict; use warnings; $d = 'aaa'; while( $d =~ /(\w+)/g ) { print "$1\n"; $d = 'aaa'; } where difference between 2 scripts? missing?
the position @ //g left off stored in magic added scalar against matching performed.
$ perl -mdevel::peek -e'$_ = "abc"; dump($_); /./g; dump($_);' sv = pv(0x32169a0) @ 0x3253ee0 refcnt = 1 flags = (pok,iscow,ppok) pv = 0x323bae0 "abc"\0 cur = 3 len = 10 cow_refcnt = 1 sv = pvmg(0x326c040) @ 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 this means way behaviour observed possible in backticks example if match operator matched against same scalar 4 times evaluated! how possible? it's because backticks 1 of operators uses targ.
creating scalar relatively expensive since requires 3 memory allocations! in order increase performance, scalar called targ associated each instance of operators. when operator targ evaluated, may populate targ value return , return targ (rather allocating , returning new one).
"so what?", might ask. after all, you've demonstrated assigning scalar resets match position associated scalar. that's what's suppose happen, doesn't backticks.
magic not allows information attached variable, attaches functions called under conditions. magic added //g attaches function should called after scalar modified (which indicated smg flag in dump above). function clears position when value assigned scalar.
the assignment operator handles magic properly, not backticks operator. doesn't expect magic have been added targ, doesn't check if there's any, function clears match position goes uncalled.
Comments
Post a Comment