in reply to Scope of regular expression variables

According to the camel book (page 65 in 2nd edition for those of you keeping score at home),
The variables $1, $2, $3 ... are automatically localized, and their sc +ope extends to the end of the enclosing block or eval string, or to t +he next successful pattern match, whichever comes first.
So, your $1 is "stomped" within the local scope of the enclosing braces. To elaborate:
if ($_ =~ /ORG\:(.+)/) { # $1 in scope A if ($1 =~ /^(.+)\;(.+)\;(.+)$/) { # $1 now in scope B $card{'org'}=$1; $card{'div'}=$2; $card{'dept'}=$3; } # $1 now in scope A again elsif ($1 =~ /^\;(.+)\;(.+)$/) { # $1 now in scope C
Update: See merlyn's clarification below. Seems either (a) I didn't understand the book correctly, or (b) he (or Larry or Tom) should've written it clearer. ;-)
Hope that helps,
Shendal

Replies are listed 'Best First'.
RE: Re: Scope of regular expression variables
by merlyn (Sage) on Aug 29, 2000 at 23:21 UTC
    Uh, not quite. It's because it's a failed match. Apparently, the block that localizes the match variables doesn't begin until after the open curlies (and does not include the boolean expression of the if). Check this:
    $_ = "abcde"; if (/(.)(.)/) { # first two if (/(.)(.)$/) { # last two, by your theory won't upset print "inner: $1 $2\n"; } # by your theory, should see first two again print "outer: $1 $2\n"; }
    for which I get
    inner: d e outer: d e
    But if you add a block:
    $_ = "abcde"; if (/(.)(.)/) { # first two { # ADDED if (/(.)(.)$/) { # last two, by your theory won't upset print "inner: $1 $2\n"; } } # ADDED # by your theory, should see first two again print "outer: $1 $2\n"; }
    we do in fact get the expected:
    inner: d e outer: a b

    -- Randal L. Schwartz, Perl hacker

      It works that way for manual localization in the conditional as well. That's fairly counterintuitive considering that my() does the opposite.
      ($one, $two) = (1,2); { if (local ($one, $two) = qw(abc def)) { print "local inner : $one $two\n"; } print "local outer : $one $two\n"; } print "local outside: $one $two\n"; my ($a, $b) = (1,2); { if (my ($a, $b) = qw(abc def)) { print "my inner : $a $b\n"; } print "my outer : $a $b\n"; } print "my outside: $a $b\n"; __END__ local inner : abc def local outer : abc def local outside: 1 2 my inner : abc def my outer : 1 2 my outside: 1 2

      The behavior of the regex vars is similar to what is obtained by using "local" inside the if() conditional.

      I've modified Merlyn's code to show that the value of regex vars is sustained through a function call.

      sub PrintRegExVar { print "Inside called sub: $1 $2\n"; } $_ = "abcde"; if (/(.)(.)/) { # first two if (/(.)(.)$/) { # last two # # This prints "d e" # print "inner: $1 $2\n"; &PrintRegExVar; } # # This also prints "d e" # print "outer: $1 $2\n"; &PrintRegExVar; } $_ = "abcde"; if (/(.)(.)/) { # first two { # ADDED EXTRA BLOCK if (/(.)(.)$/) { # last two # # This prints "d e" # print "inner: $1 $2\n"; &PrintRegExVar; } } # ADDED EXTRA BLOCK # # This prints "a b" # print "outer: $1 $2\n"; &PrintRegExVar; } __END__ inner: d e Inside called sub: d e outer: d e Inside called sub: d e inner: d e Inside called sub: d e outer: a b Inside called sub: a b
      I'm not sure whether I disagree or not. To wit:
      $_ = "abcde"; if (/(.)(.)/) { # first two if (/(.)(.)$/) { print "inner: $1 $2\n"; } print "outer: $1 $2\n"; } print "outer: $1 $2\n";
      $1 and $2 aren't localized within the if block -- unless the regex is also within the same enclosing block.

      (At least, that makes it more explicit.)