http://www.perlmonks.org?node_id=967101

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

A funny thing happened to me today. I created a little piece to check weather a text file has multiple same lines.

@comp=("seed"); while ($line = <>) { push(@comp, $line); if ($comp[0] =~ $comp[1]){print $line;} shift(@comp); }

So I thought it should work fine unless the first line would be "seed" in which case it would also printed out. To test this I created a text file which had first line "seed". Funny .. but the code found out all the actual redundant lines and did not declare the first line to be redundant. (which actually is a good thing I guess).

But as I look and look at this simple piece of code I cannot in my mind understand why the first match (which should be between array elements "seed" and "seed") doesn't evaluate true)

Can anyone enlighten me?

Replies are listed 'Best First'.
Re: my code works just fine, but how :D
by BrowserUk (Patriarch) on Apr 25, 2012 at 16:07 UTC

    "seed" ne "seed\n";

      Aah - how dreadfully obvious. Well id say its one of those days, but it has more been a week like that already. Thank you folks, that is all.
Re: my code works just fine, but how :D
by JavaFan (Canon) on Apr 25, 2012 at 16:29 UTC
    All the lines will end in a new line. But you're seeding @comp with a string that doesn't have a newline. So, on the first run, the only way you get a match if your file contains 4 characters: s, e, e and d, and no newline.
      Not true. A first line of "|\n" would also match, for example. Fix:
      my @comp = "seed\n"; # Fix 1 while ($line = <>) { push(@comp, $line); print $line if $comp[0] =~ /^\Q$comp[1]\E\z/; # Fix 2 shift(@comp); }

      But why not just use eq?

      my @comp = "seed\n"; while ($line = <>) { push(@comp, $line); print $line if $comp[0] eq $comp[1]; shift(@comp); }

      Simpler still:

      my $last = ""; while (<>) { print if $_ eq $last; $last = $_; }