Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses

Re: Using @- & @+

by RollyGuy (Chaplain)
on Aug 08, 2002 at 17:20 UTC ( #188652=note: print w/replies, xml ) Need Help??

in reply to Using @- & @+

The foreach in from perlretut goes through the numbers associated with the matches in the parentheses. So ${$_} in the code above evaluates to ${1} which is $1. $1 is the captured match from in the first set of parens. That's why you see 'Mmm'.

Now as far as your code goes, I believe that your for loop should loop over (1..$#-), or the actual matches. If you look at the @+ array, you see that it has the correct number of elements, but they aren't all defined (because we only used the first match in the parens).

Update: I forgot to ask what you expected to see as the output. I was going to suggest a code change, but it depends on what you are trying to see as output.

Replies are listed 'Best First'.
Re: Re: Using @- & @+
by BrowserUk (Patriarch) on Aug 08, 2002 at 20:47 UTC

    Below is a better reduction of the original code that gave me a problem and started me down this road.

    I am not quite sure what you mean by I believe that your for loop should loop over (1..$#-)? As opposed to 1..$#+?

    perlvar says:

    You can use $#- to determine how many subgroups were in the last successful match

    and You can use $#+ to determine how many subgroups were in the last successful match

    Doesn't this mean they should be the same?

    Update:I just found this in Japhy's book...

    The last index of @-, $#-, is the number of the last matching back-reference (and so can be used to find out which $DIGIT variable $+ corresponds to), whereas the last index of @+, $#+, is the number of back-references, defined or not

    Which explains things somewhat. And there was I just getting comfortable with the $#array idiom:(

    End update

    With regard to ${1} eq $1....see below, using $1 in the first print inside the for loop gives "abc". Using ${$_} (where $_ = 1) results in the error?

    I'd assume this was a throw-over from pre-strict Perl days except that (from what I read) @- & @+ didn't arrive until 5.6.

    As for what I was trying to acheive.... I am only slightly embarassed to admit that I thought that the @- & @+ arrays would give me the start/stop indexs for each captured match when used with the //g option. I now see that this was wrong, but that is why I am playing with regexs...I'm attempting to understand what they can do (and how). It saddens and confuses me slightly that someone actually bothered to downvote my original question. I always thought that the only bad question was the one you didn't ask. C'est la vie.

    #! perl -w use strict; my $haystack = "abcdefghijklmnopqrstuvwxyz"; my @needles = qw(abc cde fgh ghi ijk pqr rst xyz); my $regex = '(' . join('|', @needles ) . ')'; print "Pre-compilation:", $regex,$/; $regex = qr/$regex/s; print "Post-compilation:", $regex, $/; $haystack =~ /$regex/g; if ($#-) { print "$#+ matches found", $/; for (1..$#+) { print "\$_ is $_, & \$1 is $1", $/; print "$haystack contains ${$_} at $-[$_]", $/; } } __END__ C:\test>test Pre-compilation:(abc|cde|fgh|ghi|ijk|pqr|rst|xyz) Post-compilation:(?s-xim:(abc|cde|fgh|ghi|ijk|pqr|rst|xyz)) 1 matches found $_ is 1, & $1 is abc Can't use string ("1") as a SCALAR ref while "strict refs" in use at C +:\test\ line 19. C:\test>
      Using ${$_} this way is called a "symbolic reference" or a "soft reference". use strict doesn't allow the use of symrefs. For example:

      #use strict; #uncomment to kill the code my $s = 'foo'; $$s = 'bar'; print "\$foo = $foo\n"; $foo = 'baz; print "\$\$s = $$s\n"; __END__ Output: $foo = bar $$s = baz

      $$s is $foo in this case - using a variable for a variable name. There's a huge rant here by Mark-Jason Dominus (at the bottom, there are links to part 2 and part 3) about symbolic references and why they are bad. It's a good read. I love it when he says

      "Yeah, well, there's no problem with smoking in bed, either, as long as you don't fall asleep and burn the house down."

      That said, symrefs have their place in perl. If you know you want symrefs, put no strict 'refs'; in the smallest possible scope and they will work inside of that scope. In your case, try:

      if ($#-) { no strict 'refs'; print "$#+ matches found", $/; for (1..$#+) { print "\$_ is $_, & \$1 is $1", $/; print "$haystack contains ${$_} at $-[$_]", $/; } }

      ${$_} will now expand to $1 and print the value of $1.

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://188652]
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others musing on the Monastery: (1)
As of 2022-08-09 23:58 GMT
Find Nodes?
    Voting Booth?

    No recent polls found