in reply to Re: Using @- & @+
in thread Using @- & @+

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\test.pl line 19. C:\test>

Replies are listed 'Best First'.
Re: Re: Re: Using @- & @+
by jsprat (Curate) on Aug 08, 2002 at 21:33 UTC
    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.