http://qs1969.pair.com?node_id=549400

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

hi monks

I have a little confusion in the below code's behaviour. I found that the builtin variable $& is not having the reliable value in it. Initially I tried to print the values available in $` and $'. but I found a misleading answer when I print $&.
I picked this code from a very large program. I beleive that monks can definitely clear my doubts.

$_ = foo; /foo/; # prints "bar\n" for (qw/bar baz/) { print "$&\n" unless /bar/; } # prints "foo\n" for (qw/bar baz/) { next if /bar/; print "$&\n"; }

"Keep pouring your ideas"

Replies are listed 'Best First'.
Re: The value of pattern match variable $&
by McDarren (Abbot) on May 15, 2006 at 10:17 UTC
    I don't have my copy handy, but I'm almost certain that PBP recommends against using $`, $' and $&. Mainly because of the fact that they are global, and if you have several pattern matches in your code you can never be sure which variable was set by which match.

    Much better instead to use explicit locally-scoped variables, and capturing parentheses, eg:

    my ($prematch, $match, $postmatch) =~ /^(foo)(bar)(baz)$/;

    Cheers,
    Darren :)

      IIRC, there is also a big performance hit, if any of these appear anywhere in your program.

        Regexps without captures are faster than regexps with captures. Using any of those three variables causes all regexps in that interpreter instance (similiar to "in that process") to behave as if they had captures. That slows down all regexps without captures.
Re: The value of pattern match variable $&
by cdarke (Prior) on May 15, 2006 at 09:04 UTC
    perlvar defines $& ($MATCH) with the cavet "not counting any matches hidden within a BLOCK", and yours are, although I admit surprise at the behaviour.
      It's by design. There's an implicit local for match variables in blocks.

      And re "reliability": a regexp that doesn't match will not affect the match variables, they will not (necessarily) be undef, but the value they got on the last succesful regexp — with the above caveat.

        That doens't quite explain it. It the first loop, it's as if the implicit local $& is outside of the loop — It prints 'bar' on the 'baz' pass of the loop — while in the second loop, it's as is the implicit local $& is inside of the loop.

        Could
        print "$&\n" unless /bar/;
        suffer from a problem similar to the one from which
        my ... if ...;
        suffers?

Re: The value of pattern match variable $&
by Anonymous Monk on Nov 29, 2007 at 00:44 UTC
    ok that is not cool i am looing for varbles not a code