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

UPDATE: I am an idiot, in my code I did a copy paste error and reinstantiated my nextline inside the while loop with...

while(...) { my $nextline = <IN> ..... }

That I am assuming was scoped within the while loop. So I guess if a mod could delete this, that would be super.

So I am trying to write some code to skip over empty lines in some rather large files, so I am trying...

my $nextline = <IN>; while($nextline eq '') { $nextline = <IN>; print"Nextline is empty\n"; }

If I am reading a file with EMPTY LINE,EMPTY LINE,EMPTY LINE,EMPTY LINE,4,5 and 6 each on a new line.

my print statements will be

Nextline is

Nextline is

Nextline is

Nextline is

Nextline is 4 # SHOULD EXIT THE WHILE LOOP

Nextline is 5 # BUT STILL IN IT

Nextline is 6 # STILL IN IT!

So my nextline is getting updated correctly, but it doesn't seem that the condition for the while loop is using it?

I know my logic is right since if I insert an if stmt that checks the same conditon...

... if($nextline ne '') { last; } ...

It exits exactly how I want it to. So I am assuming conditions for while loops in perl are not behaving as one would normally expect.

Replies are listed 'Best First'.
Re: While loop conditions in Perl
by cheekuperl (Monk) on Jul 18, 2012 at 21:35 UTC
    chomp $nextline before you compare it with anything.

    So I am assuming conditions for while loops in perl are not behaving as one would normally expect.
    That is assuming WAY TOO MUCH!
Re: While loop conditions in Perl
by aaron_baugher (Curate) on Jul 18, 2012 at 21:50 UTC

    A more perlish way to do this, and the way that confines your variable to the scope of the loop, is like this:

    while( my $nextline = <IN> ){ chomp; last unless $nextline eq ''; # exits the loop unless empty line print "Nextline is empty\n"; } # now $nextline goes out of scope

    UPDATE: Yes, as cheekuperl noticed, that should be chomp $nextline;

    Aaron B.
    Available for small or large Perl jobs; see my home node.

      I was wondering if chomp statement in your code should be like :
      chmop $nextline; #chomp uses $_ by default

        Well I actually don't use chomp anymore, I can't really explain it but I have come across files that just didn't agree with chomp. So I use...

        $string =~ s/^\s+//; $string =~ s/\s+$//;

        To remove any whitespace(including newlines) before the first character and after the last character on the line, as well as...

        @fi = split(/\s+/, $nextline);

        ... to break apart the line by spaces.

        This whole issue I was having actually initiated with my while loop being constructed with...

        while(@fi[0] eq'') { $nextline = readline<IN>; //remove whitespace //split the line, but I think I included my accidentally so that +I had my @fi = split..... }

        ...so that I also changed my scope inside the while loop accidentally by using...

         my $nextline = ...

        instead of...

         $nextline = ...
Re: While loop conditions in Perl
by Kenosis (Priest) on Jul 18, 2012 at 22:23 UTC

    How about the following:

    use Modern::Perl; print for grep /\S/, <DATA>; __DATA__ This is not a blank line. This is not a blank line. This is not a blank line. This is not a blank line.

    Output:

    This is not a blank line. This is not a blank line. This is not a blank line. This is not a blank line.
Re: While loop conditions in Perl
by aitap (Curate) on Jul 18, 2012 at 21:49 UTC
    while (defined my $line = <IN>) { # read all data in one while(){} chomp $line; # remove \n from the end of the line next if $line eq ''; # skip empty lines ... }
    EDIT: chomp instead of chop
    Sorry if my advice was wrong.

      chop is going to truncate your data if you don't have a \n on the last line.

      Are you sure that you'll be getting \n after every line ever?

        Sorry! It was a misprint. chomp will do it better.
        Sorry if my advice was wrong.
Re: While loop conditions in Perl
by Marshall (Canon) on Jul 19, 2012 at 07:31 UTC
    The "while" loop works just like in 'C'.
    More normal is the second example below.... Do something or process the lines that are "not blank", rather than find the first one.

    Note that /^\s$/ means a regex that starts at the beginning to the end of the input and comprises all 5 white space characters
    [ \t\f\r\n]

    #!/usr/bin/perl -w use strict; my $firstNonBlankLine; while ($firstNonBlankLine = <DATA>, $firstNonBlankLine !~ /\S/){} print $firstNonBlankLine; =prints This first non-"blank" line =cut __DATA__ This first non-"blank" line this is second non-blank line
    Second Example:
    Perhaps to print all the non-blank lines...
    #!/usr/bin/perl -w use strict; while (<DATA>) { print if !/^\s$/; } =prints This first non-"blank" line this is second non-blank line =cut __DATA__ This first non-"blank" line this is second non-blank line