Mubby has asked for the wisdom of the Perl Monks concerning the following question:

I've come across a problem when using the perl redo statement. I created a small script (see below) which reproduces the problem.

On a Linux machine with perl 5.12.0, the script works; it has problems on an AIX machine with perl 5.8.2.

#!/usr/local/bin/perl use strict; my ($file) = @ARGV; open( FH, "<", $file ) or die "$!"; while( my $line = <FH> ) { chomp( $line ); if( $line =~ /^#/ ) { redo; } else { print "Doesn't begin with #\n"; } }

Note: the file that is opened and read contains a single '#' character in the first position.

The "correct" case: perl 5.12.0

When running in the perl debugger, and watching $line, after the redo statement executes, the code correctly jumps to the chomp statement, without reevaluating the while-condition, and without anything happening to the $line variable. (Note that, with this code sample, this will induce an endless loop. In the 'real' code, there are other things happening which would prevent this.)

The "weird" case: perl 5.8.2

When stepping through with the debugger here (same code, same input file), and watching $line, after the redo statement executes, and before executing the chomp statement, this displays:

main::(jt:12): redo; DB<2> Watchpoint 0: $line changed: old value: '#' new value: '' main::(jt:9): chomp( $line );

Notice how the $line just changed for no reason (from pound to undef).

I understand that the ideal thing here is to upgrade to 5.12 across the board, but there are many machines involved and that's not possible at the moment.

Am I hitting something known? I've Googled around for "perl redo bug", etc, but cannot locate anything.

UPDATE

By taking the my out of the while-condition, and declaring my $line just above the while condition, this seems to fix the problem. However, I still wonder why.

Replies are listed 'Best First'.
Re: Does perl 5.8.2 have a bug with 'redo' statement
by repellent (Priest) on May 20, 2010 at 22:29 UTC
    perl589delta states:
      while (my $x ...) { ...; redo } shouldn't undef $x.

      In the presence of my in the conditional of a while(), until() , or for(;;) loop, we now add an extra scope to the body so that redo doesn't undef the lexical.
Re: Does perl 5.8.2 have a bug with 'redo' statement
by ikegami (Patriarch) on May 20, 2010 at 19:06 UTC

    I understand that the ideal thing here is to upgrade to 5.12 across the board, but there are many machines involved and that's not possible at the moment.

    You should check if it was fixed by 5.8.9. Upgrading to 5.8.9 would be quite simple as it wouldn't require modules to be reinstalled.

    Am I hitting something known?

    You've shown that it was fixed, so it would seem it was known to someone.

    I still wonder why.

    Probably because the programmer overlooked something.

Re: Does perl 5.8.2 have a bug with 'redo' statement
by 7stud (Deacon) on May 21, 2010 at 05:19 UTC

    I think the following is equivalent to your code:

    while( my $line = <FH> ) { while (1) { chomp( $line ); last if $line !~ /^#/; } print "Doesn't begin with #\n"; }
      Or if the extra scope is a problem,
      while( my $line = <FH> ) { REDO: chomp( $line ); if( $line =~ /^#/ ) { goto REDO; } print "Doesn't begin with #\n"; }

        Everyone-- thanks for the insights.