in reply to Re^2: Side effect of using undefined variable in regex
in thread Side effect of using undefined variable in regex

Ok, I've looked at it a little further now. I omitted a bit in my quote from perlop:

If the PATTERN evaluates to the empty string, the last successfully matched regular expression is used instead. ... If no match has previously succeeded, this will (silently) act instead as a genuine empty pattern (which will always match).

I think there is something omitted from the documentation - AnomalousMonk describes this as well:

$ perl -le'print"x"=~//?"yes":"no"; "y"=~/y/; print"x"=~//?"yes":"no"' yes no $ perl -le'print"x"=~//?"yes":"no";{"y"=~/y/} print"x"=~//?"yes":"no"' yes yes

So in other words, the "last successfully matched regular expression" means the "last successfully matched regular expression in this scope", which explains why the successful match when $last is "Config" doesn't affect the other matches. I stumbled on this at first; I think it might be worth a documentation patch...

Anyway, that means in the OP's example, we can remove startStandardServices('Config') since that's working as expected, and since the other two calls of startStandardServices and startGeneralServices are seeing the same issue each, the script can be reduced to:

use warnings; use 5.014; my @stoppedGeneralServices = ('OP Mover', 'OP Monitor'); my $supported = '4.0.0,4.0.1,4.1.0,4.1.1,4.1.2'; $supported =~ /\Q4.1.2/ if @ARGV; startGeneralServices(); sub startGeneralServices { my $last = shift; my $name; while (@stoppedGeneralServices) { $name = pop @stoppedGeneralServices; say ' Starting $name=\'', $name, '\' $last=', defined $last ? "'$last'" : 'undef', ' ($name=~/$last/i)=', ($name =~ /$last/i) ? 1 : 0; last if $name =~ /$last/i; } }

And taking that a few steps further:

use warnings; use 5.014; '4.1.1,4.1.2' =~ /\Q4.1.2/ if @ARGV; my $last = ''; my $name = 'OP Mover'; say '$name=\'', $name, '\' $last=', defined $last ? "'$last'" : 'undef', ', $name=~/$last/i = ', ($name =~ /$last/i) ? 1 : 0;
$ perl 11102215.pl $name='OP Mover' $last='', $name=~/$last/i = 1 $ perl 11102215.pl all $name='OP Mover' $last='', $name=~/$last/i = 0

Which shows that:

Replies are listed 'Best First'.
Re^4: Side effect of using undefined variable in regex
by Eily (Monsignor) on Jul 01, 2019 at 14:39 UTC

    I've edited my post because putting the (?{ }) block after trying to match 4.1.2 was the obvious reason why it didn't called again. But I've tried this:

    use v5.20.0; my @stoppedStandardServices = ( 'OP OPC Client', 'OP Calculation Serve +r', 'OP Data Server', 'OP Configuration Server', 'OP Log Server', 'OP + Time Server', 'ONC RPC PortMapper'); my $supported = '4.0.0,4.0.1,4.1.0,4.1.1,4.1.2'; $supported =~ /.(?{say '>>> In the regex'})/ if @ARGV; "4.1.2" =~ //; say "Start Basic Standard Services:"; startStandardServices( 'Config'); say "Start Remaining Standard Services:"; startStandardServices(); say "Installation completed"; sub startStandardServices { my $last = shift; my $name; while (@stoppedStandardServices) { $name = pop @stoppedStandardServices; say ' Starting $name=\'', $name, '\' $last=', defined $last ? + "'$last'" : 'undef', ' ($name=~/$last/i)=', ($name =~ /$last/i) ? 1 +: 0; last if $name =~ /$last/i; } }
    And with one parameter I get the output:
    >>> In the regex >>> In the regex Start Basic Standard Services: Starting $name='ONC RPC PortMapper' $last='Config' ($name=~/$last/i) +=0 Starting $name='OP Time Server' $last='Config' ($name=~/$last/i)=0 Starting $name='OP Log Server' $last='Config' ($name=~/$last/i)=0 Starting $name='OP Configuration Server' $last='Config' ($name=~/$la +st/i)=1 Start Remaining Standard Services: 'Config' Starting $name='OP Data Server' $last=undef ($name=~/$last/i)=1 'Config' Installation completed
    Why doesn't ">>> In the regex" appear again when $last is undef, and how is the string 'Config' printed?

      Why doesn't ">>> In the regex" appear again when $last is undef, and how is the string 'Config' printed?

      Sorry, I can't reproduce that on any of my Perl builds, 5.20.0 through 5.30.0 (Linux). The output I get in all cases is:

      >>> In the regex >>> In the regex Start Basic Standard Services: Starting $name='ONC RPC PortMapper' $last='Config' ($name=~/$last/i) +=0 Starting $name='OP Time Server' $last='Config' ($name=~/$last/i)=0 Starting $name='OP Log Server' $last='Config' ($name=~/$last/i)=0 Starting $name='OP Configuration Server' $last='Config' ($name=~/$la +st/i)=1 Start Remaining Standard Services: >>> In the regex Starting $name='OP Data Server' $last=undef ($name=~/$last/i)=1 >>> In the regex Installation completed

        I don't get it on Linux either. Only on my 5.26 strawberry perl...

Re^4: Side effect of using undefined variable in regex
by AnomalousMonk (Archbishop) on Jul 01, 2019 at 16:51 UTC
    ... the "last successfully matched regular expression" means the "last successfully matched regular expression in this scope" ... I think it might be worth a documentation patch...

    I've been looking for an explicit discussion of this. Best I can come up with, and it's very indirect, is in Variables related to regular expressions:

    The dynamic nature of the regular expression variables means that their value is limited to the block that they are in ...
    I'm sure I've seen something better, more to the point. Not much time to look ATM.


    Give a man a fish:  <%-{-{-{-<

      I've been looking for an explicit discussion of this.

      Me too... I also found a few similar mentions in perlre:

      Capture group contents are dynamically scoped and available to you outside the pattern until the end of the enclosing block or until the next successful match, whichever comes first. ... These special variables, like the %+ hash and the numbered match variables ($1, $2, $3, etc.) are dynamically scoped until the end of the enclosing block or until the next successful match, whichever comes first.

      But I think the language regarding // is pretty direct, if IMHO misleading: "the last successfully matched regular expression is used". No mention of scope anywhere even near that statement...