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

Hello, I am new to Perl and I have a question, perhaps is a little but silly but I have a txt doc with several lines where each line is a programming language and I want to print allthe lines except for Java, and I have this piece of code but it doesn't do anything, it stays at: "Reading file", I would appreciate any help or if you know of a link where I can further study the next-unless, Thanks.
open(FH, "/Users/anaordonez/Documents/my_languages.txt")or die "Sorry! +! couldn't open"; print "Reading file \n"; # Reading the file till FH reaches EOF while(<>) { # Printing one line at a time next unless $_ = "Java"; print $_; } close;

Replies are listed 'Best First'.
Re: next unless not working
by Fletch (Bishop) on Feb 05, 2025 at 17:03 UTC

    You used = not eq which is what you want checking for string equality (had you wanted numeric equality it'd still be == instead). If you'd used the warnings pragma like is recommended you'd have gotten a message to this effect.

    Found = in conditional, should be == at foo.pl line 9.

    Edit: I missed the other problem which is that you're iterating over <> which will read from stdin (which is why it's just sitting there waiting for you to type at it); to read from the file you opened you should use the name of the filehandle <FD>. Again warnings would have griped that you hadn't used FD.

    And another thing: Your last line should also use the name of the filehandle to let perl know what you want to close:

    close( FD ) or warn qq{Problem closing FH: $!\n};

    And again: Get in the habit of using $! in your error messages. You're checking that the open failed but your text is lacking. Including both the path you're trying to operate on as well as $! to indicate WHAT went wrong will save yourself headaches down the road.

    The cake is a lie.
    The cake is a lie.
    The cake is a lie.

Re: next unless not working
by jo37 (Curate) on Feb 05, 2025 at 17:24 UTC

    Yet another thing: $_ in your loop will contain the line separator and will therefore never be equal to "Java".

    You may chomp the input or perform a regex match /^Java$/ instead of $_ eq "Java"

    Greetings,
    🐻

    $gryYup$d0ylprbpriprrYpkJl2xyl~rzg??P~5lp2hyl0p$
      > never be equal

      Well, the last line could, if it didn't end in a newline. But that's definitely not what was expected.

      map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]
Re: next unless not working
by johngg (Canon) on Feb 05, 2025 at 22:11 UTC

    The OP wants to print all the lines except "Java" but nobody seems to have noticed that the logic is reversed and will print only "Java." Doing

    while ( <FH> ) { print unless /^Java\z/; }

    should suffice. The task could be done as one-liner.

    johngg@aleatico:~$ cat langs Fortran JavaScript Cobol Go Java Haskell johngg@aleatico:~$ perl -ne 'print unless /^Java\z/' langs Fortran JavaScript Cobol Go Haskell

    I hope this is helpful.

    Update: Added JavaScript and updated regex as per choroba's comment.

    Cheers,

    JohnGG

      JavaScript is missing in the list. *wink*

      map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]

      Derp; three edits and two other follow-ups later and I hadn’t noticed that either. Good catch.

      The cake is a lie.
      The cake is a lie.
      The cake is a lie.

Re: next unless not working
by marto (Cardinal) on Feb 05, 2025 at 17:19 UTC

    Welcome! Unrelated to the question that has been answered above, consider open, note the three argument form of open, and the use of $! to display why opening failed when calling die. See also Three-arg open().

      Good point. Playing around with qwen2.5-coder it came up with the below version incorporating both this suggestion and some of mine.

      use warnings; use strict; my $file_path = "/Users/anaordonez/Documents/my_languages.txt"; open(my $fh, '<', $file_path) or die "Sorry!! couldn't open '$file_pa +th': $!"; print "Reading file \n"; while (my $line = <$fh>) { chomp $line; print "$line\n" if $line eq "Java"; } close($fh);

      The cake is a lie.
      The cake is a lie.
      The cake is a lie.

        Curious, does the LLM explain why these changes should be made? If so can you please post the output?