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

#Here is the Input Enter a number (999) to quit 1 2 3 4 999
#Actual Script #!/usr/bin/perl use strict; use warnings; sub add_nums { # body... # Add numbers entered at STDIN print "Enter a number (999) to quit\n"; chomp(my $n = <>); my $sum = 0; while ($n != 999) { $sum += $n; chomp($n = <>); } print "The Sum is $sum\n"; } add_nums;
#Output The Sum is 10
The script basically adds all the numbers entered at STDIN until it encounters 999. Two Questions:
1. Is Chomp here being used to chop the new line character after the while loop exists?
2. If so, why doesn't the while loop just exist after encountering 999 and print the result in $sum ?
Thanks.

Replies are listed 'Best First'.
Re: confusion with Chomp
by stevieb (Canon) on Apr 08, 2016 at 00:13 UTC

    It removes the newline after the first assignment to $n prior to the loop, then unless the initial $n is 999, it'll step into the while(). You continue to remove the newline as each new STDIN is accepted, prior to the while() condition being checked again.

    So effectively, inside the while, you chomp the input *before* the while is checked again. No chomp happens after the while, just the printing of the sum.

    Does that help?

      Thank you so much, this explains how the chomp is working. cheers
Re: confusion with Chomp
by Marshall (Canon) on Apr 08, 2016 at 00:08 UTC
    Your code does run. For explanation of chomp, look at chomp perl doc. In this case, chomp removes 2 bytes at the end of the string (on Windows), the "\r\n" characters. If you run it on Unix, this will only remove one byte, the "\n".

    In this case, the chomp is not needed and your code runs fine without it. Perl considers these line endings as "whitespace" and this doesn't factor into the conversion between "string" and "numeric". Try entering " 3 ", etc leading whitespace and trailing whitespace won't matter.

    #Actual Script #!/usr/bin/perl use strict; use warnings; sub add_nums { # body... # Add numbers entered at STDIN print "Enter a number (999) to quit\n"; (my $n = <>); my $sum = 0; while ($n != 999) { #causes string to numeric for $n $sum += $n; ($n = <>); } print "The Sum is $sum\n"; } add_nums;
      In this case, chomp removes 2 bytes at the end of the string (on Windows), the "\r\n" characters.

      The behavior of chomp is independent of OS. Perl's I/O operators translate whatever our operating system uses for a newline into a perl newline character. (This conversion is not necessary in UNIX.) Even in windows, The default value for $INPUT_RECORD_SEPARATOR is "\n". As your reference specifies, this is what is removed by chomp.

      The only documentation I can find for this is in binmode. The primary purpose of binmode is to turn off the newline translation. Perhaps someone can provide a more direct reference.

      Bill
        Yes, "The behavior of chomp is independent of OS", True. Perl chomp will work fine across platforms. The "\n" in Perl generically means the "end of line" character(s).

        On Windows, this means "carriage return, line feed". On Unix a single "line feed" is used, implying the "carriage return". I have a setup that allows me to use my local Windows Text editor to edit remote Unix files. When I send the file back to Unix, it can have mixed line endings (sometimes just a line feed and sometimes a carriage return and a line feed). Perl doesn't care about this and it not an issue. Some Unix utilites are not as "forgiving".

        The easy way to "normalize" the line endings to the current platform:

        while (<>) { chomp; #removes line endings of both varieties print "$_\n"; #prints with this platform's line endings. }
        My main point was that chomp() is not needed because in this case, the line ending character(s) count as white space.