puterboy has asked for the wisdom of the Perl Monks concerning the following question:

Perhaps this is obvious, but the behavior of this short code snippet confused me (actually it was buried in more complicated code that wasn't working for me), until I realized the potential indirect consequences of passing by reference... I pass it along for interest since at least for me the behavior was non-obvious...
my $bar = "abc"; foo($bar); $bar =~ /(.*)/; my $val = $1; foo($val); foo($1); print "|$1|$bar|\n"; sub foo { print "$_[0]\n"; $_[0] =~ /(.)/; print "$_[0]\n\n"; }
The result is:
abc abc abc abc abc a |abc|abc|

Replies are listed 'Best First'.
Re: Side effect of passing matched values by reference
by choroba (Cardinal) on Feb 21, 2013 at 17:22 UTC
    That is not a consequence of passing by reference, in fact. It is a consequence of aliasing. See perlsub for details. This would not happen if you use a different variable than @_:
    sub foo { my $x = $_[0]; print "$x\n"; $x =~ /(.)/; print "$x\n\n"; }
    لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ
      Of course - that was the solution I used. My point was just that it wasn't obvious (at least to me) that $1 acts like a global variable in that way...
Re: Side effect of passing matched values by reference
by LanX (Saint) on Feb 21, 2013 at 17:47 UTC
    Please ...

    $1 is a global variable which should only be carefully used in local context.

    But your match within the sub changes this global variable and your alias in $_[0] reflects this.

    And after leaving the sub the implicit localization restores the old value of $1...

    Better stop messing with perl internals or just pass a copy of $1 or follow chorobas suggestion.

    Cheers Rolf