Effect of redo on m//g

Discussion in 'Perl Misc' started by Mark, Jun 30, 2009.

  1. Mark

    Mark Guest

    Can someone please explain to me how the redo is affecting the match
    results?

    Case 1 - without redo:
    use strict;
    use warnings;

    my $bail = 0;

    while () {
    'ab' =~ /(.)/g;
    print "\$1=", defined($1) ? $1 : 'undef', "\n";
    last if $bail++ > 5;
    # redo;
    }

    Output:
    $1=a
    $1=b
    $1=b
    $1=a
    $1=b
    $1=b
    $1=a

    Case 2 - with redo:
    use strict;
    use warnings;

    my $bail = 0;

    while () {
    'ab' =~ /(.)/g;
    print "\$1=", defined($1) ? $1 : 'undef', "\n";
    last if $bail++ > 5;
    redo;
    }

    Output:
    $1=a
    $1=b
    $1=undef
    $1=a
    $1=b
    $1=undef
    $1=a

    It seems to me that redo should have no affect in the second case
    below. It appears that when pos is past the end of the string, $1 is
    not set in Case 1 but it is reset to undef in Case 2.
    Mark, Jun 30, 2009
    #1
    1. Advertising

  2. Mark

    Bo Lindbergh Guest

    In article <>,
    Mark <> wrote:

    > use strict;
    > use warnings;
    >
    > my $bail = 0;
    >
    > while () {
    > 'ab' =~ /(.)/g;
    > print "\$1=", defined($1) ? $1 : 'undef', "\n";
    > last if $bail++ > 5;
    > # redo;
    > }


    An unsuccessful match doesn't modify $1 and friends, so you should
    in general only look at their values after a successful match.


    /Bo Lindbergh
    Bo Lindbergh, Jun 30, 2009
    #2
    1. Advertising

  3. Mark

    C.DeRykus Guest

    On Jun 30, 4:14 pm, Ben Morrow <> wrote:
    > Quoth Bo Lindbergh <>:
    >
    >
    >
    > > In article <>,
    > >  Mark <> wrote:

    >
    > > > use strict;
    > > > use warnings;

    >
    > > > my $bail = 0;

    >
    > > > while () {
    > > >     'ab' =~ /(.)/g;
    > > >     print "\$1=", defined($1) ? $1 : 'undef', "\n";
    > > >     last if $bail++ > 5;
    > > > #   redo;
    > > > }

    >
    > > An unsuccessful match doesn't modify $1 and friends, so you should
    > > in general only look at their values after a successful match.

    >
    > While this is correct, it doesn't answer the question 'why, then, does
    > redo appear to be resetting $1 to undef?'. I think it's a bug in perl,
    > and IIRC it's a known (and probably won't-fix) bug. 'redo' causes perl
    > to forget which pattern was the last one you matched, and since the $N
    > are actually stored in the pattern this causes $1 to revert to the last
    > successful pattern match *before* the loop that was redone. Try adding
    >
    >     "f" =~ /(f)/;
    >
    > before the loop to see what I mean.
    >


    Interesting. Maybe, it's considered a feature :)

    (And just to be pedantic, the OP shouldn't try to
    get the "full monty" anyway if the match fails)

    --
    Charles DeRykus
    C.DeRykus, Jul 1, 2009
    #3
  4. Mark

    Mark Guest

    And.. the execution doesn't even need to reach the redo for it to have
    an effect.

    "f" =~ /(f)/;
    my $last;

    while (1) {
    "a" =~ /(a)/ unless $last;
    say $1;
    last if $last++;
    next; # <<----------
    redo;
    }
    Mark, Jul 1, 2009
    #4
  5. Mark

    C.DeRykus Guest

    On Jun 30, 5:54 pm, Ben Morrow <> wrote:
    > Quoth "C.DeRykus" <>:
    > ...


    > > (And just to be pedantic, the OP shouldn't try to
    > >   get the "full monty" anyway if the match fails)

    >
    > Both you and Bo have said that, and it *simply* *isn't* *true*. The
    > match variables being preserved across failing matches is an entirely
    > supported feature, useful in situations like
    >
    >     s/(foo)/bar/;
    >     s/(baz)/quux/;
    >
    >     my $replaced = $1;
    >


    Sigh... the OP was actually pointing out that redo
    didn't preserve the failed matches. And I see your
    subsequent post exposes the real scoping issue
    mentioned in perlre:


    The numbered match variables ($1, $2, $3, etc.)
    and the related punctuation set ($+, $& ,$`, $',
    and $^N ) are all dynamically scoped until the end
    of the enclosing block or until the next successful
    match, whichever comes first. (See ""Compound
    Statements"" in perlsyn.)

    --
    Charles DeRykus
    C.DeRykus, Jul 1, 2009
    #5
  6. Mark

    C.DeRykus Guest

    On Jun 30, 5:54 pm, Ben Morrow <> wrote:
    > Quoth "C.DeRykus" <>:
    >
    > ...
    > Both you and Bo have said that, and it *simply* *isn't* *true*. The
    > match variables being preserved across failing matches is an entirely
    > supported feature, useful in situations like
    >
    >     s/(foo)/bar/;
    >     s/(baz)/quux/;
    >
    >     my $replaced = $1;
    >


    I haven't used this feature but, it occurs
    to me, with the scoping issues you found,
    the replacement might be a bit dodgy:

    "f" =~ /(f)/;
    ...
    $_ = "one two three";
    s/(foo)/bar/;
    s/(baz)/quux/;
    my $replaced = $1; # = "f"

    > ...


    --
    Charles DeRykus
    C.DeRykus, Jul 1, 2009
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Lloyd Sheen

    Please help, cannot redo server

    Lloyd Sheen, Feb 25, 2004, in forum: ASP .Net
    Replies:
    0
    Views:
    262
    Lloyd Sheen
    Feb 25, 2004
  2. Andreas Wachhold

    Undo/Redo Java?

    Andreas Wachhold, May 4, 2004, in forum: Java
    Replies:
    2
    Views:
    4,924
    Mykola Rabchevskiy
    May 4, 2004
  3. black

    undo and redo

    black, Dec 23, 2003, in forum: Python
    Replies:
    0
    Views:
    354
    black
    Dec 23, 2003
  4. black

    undo and redo ?

    black, Jan 2, 2004, in forum: Python
    Replies:
    1
    Views:
    360
    Diez B. Roggisch
    Jan 2, 2004
  5. John Benson

    undo/redo, windows clipboard

    John Benson, Jan 2, 2004, in forum: Python
    Replies:
    0
    Views:
    350
    John Benson
    Jan 2, 2004
Loading...

Share This Page