Skip Menu |

This queue is for tickets about the NEXT CPAN distribution.

Report information
The Basics
Id: 36956
Status: resolved
Priority: 0/
Queue: NEXT

People
Owner: Nobody in particular
Requestors: norbi [...] nix.hu
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: (no value)
Fixed in: (no value)



Subject: NEXT messes up $1 and $2 passed as arguments
Date: Fri, 20 Jun 2008 16:05:08 +0200
To: bug-NEXT [...] rt.cpan.org
From: BUCHMULLER Norbert <norbi [...] nix.hu>
If $1 or $2 is passed as arguments to a sub called via NEXT, the sub will receive "NEXT" and the sub name in the corresponding arguments, instead of the original value of $1 and $2 before the $obj->NEXT::somesub(...) call. (Similarly some of the other regex punctuation vars are affected.) See the 'NEXT-regex_match_variable_bug.pl'. The problem originates from the peculiar scoping of the regex match variables, and that members of @_ are aliases to the corresponding members of the actual argument list: "The numbered match variables ($1, $2, $3, etc.) and the related punctuation set ($+, $&, $`, $', and $^N) are all dynamically scoped until he end of the enclosing block or until the next successful match, whichever comes first." from perlre "The array @_ is a local array, but its elements are aliases for the actual scalar parameters." from perlsub See 'Perl-regex_match_variable_bug.pl' and #23140 and #22369 in rt.perl.org. Now there are three ways to avoid this unintended behaviour: A) Enclosing all the code that modifies the regex vars into an inner scope inside NEXT::AUTOLOAD, and never use directly @_ from this inner scope. (We must not use @_ from inside that scope, since in the inner scope those members of @_ that are aliased to $1, $2, etc. point to the $1, $2, etc. of the last successfully matched regex in the *inner* scope.) B) Creating a copy of @_ at the beginning of NEXT::AUTOLOAD, and using that instead of @_. (This way we create a copy of each member of @_, there will be no aliases.) C) Not passing regex match- or punctuation vars as arguments. (ie. considering this behaviour as a feature) Note that local()-izing the regex match- and punctuation variables in the NEXT::AUTOLOAD will not work, first, because that would hide their previous value (and we want to pass that on, encapsulated in @_), second, because it does not work for regex vars. :-) Now, we must drop B) as copying @_ in NEXT::AUTOLOAD will break outbound parameter passing. (The user can modify the actual variables in the argument list via $_[1], $_[2], ..., and NEXT does not break it currently.) We must drop C) as well, because if someone is aware of the above problem and writes his/her subs carefully to not modify regex vars inadvertently, putting NEXT in the call chain should not ruin that. As far as I can see, there only remains A). So I created a quick and dirty fix: since in NEXT.pm we use none of the regex vars, simply wrapping all the match and substitute expressions in 'do { }' blocks does the trick of putting them in an inner scope. See 'NEXT-regex_match_variable_fix.diff'. The test cases all pass, and I also did a rough performance measurement, and it seems that the patch has no negative effect. (I also added a new testcase for this regex variable problem.) A nicer solution would require refactoring the code in the sub to separate those parts that use regex matches or substitutions in an innner scope (or inner scopes) and collect those parts that use @_ but no regexes in the outer scope. But that would be hairy, as I can see. Note: I only considered NEXT::AUTOLOAD above, but the same applies to all the other subs in NEXT.pm (and the patch fixes them, too). norbi Perl version: see 'Perl-version.txt' NEXT.pm version: 0.60

Message body is not shown because sender requested not to inline it.

Message body is not shown because sender requested not to inline it.

Message body is not shown because sender requested not to inline it.

Message body is not shown because sender requested not to inline it.

Subject: Re: [rt.cpan.org #36956] AutoReply: NEXT messes up $1 and $2 passed as arguments
Date: Fri, 4 Jul 2008 20:41:17 +0200
To: bug-NEXT [...] rt.cpan.org
From: BUCHMULLER Norbert <norbi [...] nix.hu>
Testing if $& is not modified in AUTOLOAD is a stricter constraint than checking for the modification of $1, so I changed the test suite (so it will catch regex matches that do not capture but alter the other regex vars). (And renamed the test suite to 'regex_vars.t' as it has almost nothing to do with dynamically scoped variables.:-) norbi

Message body is not shown because sender requested not to inline it.

A cleaner solution might be a core enhancement to tell a regexp match not to touch $1 and $2. I have suggested this in <http://rt.perl.org/rt3/Public/Bug/Display.html?id=58072>.