I'm looking for some clarification on chomp

I am currently taking breaks from classes and decided to spend my time learning Perl. I work with Beginning Perl ( http://www.perl.org/books/beginning-perl/ ), and I finish the exercises at the end of the third chapter.

In one exercise, they told me: "Store important phone numbers in a hash. Write a program to search for numbers by person’s name."

Anyway, I came up with this:

#!/usr/bin/perl use warnings; use strict; my %name_number= ( Me => "XXX XXX XXXX", Home => "YYY YYY YYYY", Emergency => "ZZZ ZZZ ZZZZ", Lookup => "411" ); print "Enter the name of who you want to call (Me, Home, Emergency, Lookup)", "\n"; my $input = <STDIN>; print "$input can be reached at $name_number{$input}\n"; 

And that just won't work. I kept getting this error message:

Using uninitialized value in concatenation (.) Or string on hello.plx line 17, line 1

I tried to play a little with the code, but each “solution” looked more complex than the “solution” that appeared in front of it. Finally, I decided to check the answers.

The only difference between my code and the answer was chomp ($input); after <STDIN>; .

Now the author used chomp in the previous example, but he really did not talk about what chomp doing. So, I found this answer at www.perlmeme.org:

The chomp() function will remove (usually) any newline from the end of the line. The reason we usually say it is because it actually deletes any character that matches the current value of $/ (input record separator) and $/ defaults to a new line.


Anyway, my questions are:

  • What new lines are deleted? Does Perl automatically append "\n" to input from <STDIN> ? I am a bit unclear because when I read "it actually deletes any character that matches the current value of $/ " I cannot help but think "I don’t remember to put $/ anywhere in my code."

  • I would like to develop best practices as soon as possible - is it always better to include chomp after <STDIN> or are there scripts where this is not necessary?

+7
source share
5 answers

<STDIN> reads to the end of the input line, which contains the new line, if you press return to enter it, which you are likely to do.

chomp removes the new line at the end of the line. $/ is a variable (as you found, by default for a new line) that you probably don't need to worry about; it just tells perl what the input separator is, which I assume it determines how far <FILEHANDLE> is read. At the moment, you can almost forget about it, it seems like an advanced topic. Just pretend chomp chomps from the back of the new line. Honestly, I haven't even heard of $/ before.

As is the case with your other question, it is usually easier to clean the variables and add new lines as needed later, because you do not always know if the variable has a new line or not; always changing variables, you always get the same behavior. There are scenarios in which this is not necessary, but if you are not sure that this will not interfere with chomp .

Hope this helps!

+9
source

OK, from 1), perl does not add \n to the input. You pressed Enter when you finished typing the number. If you do not specify $/ , \n will be marked by default (at least on UNIX).

Starting with version 2), chomp will be needed whenever input comes from the user or when you want to delete the line termination character (for example, reading from a file).

Finally, the error you get may be from perl, which does not understand your variable in double quotes of the last print , because it has the _ character. Try writing a line like this:

 print "$input can be reached at ${name_number{$input}}\n"; 

(note the {} around the last variable).

+3
source

<STDIN> is a short notation for readline( *STDIN ); . What readline () does is read the file descriptor until it encounters the contents of $ / (aka $ INPUT_RECORD_SEPARATOR) and returns everything that it has read, including the contents of $ /. What chomp() does is remove the contents of the last occurrence of $ /, if present.

Content is often referred to as a newline, but may contain more than one character. On Linux, it contains the LF character, but on Windows it contains CR-LF.

Cm:

 perldoc -f readline perldoc -f chomp perldoc perlvar and search for /\$INPUT_RECORD_SEPARATOR/ 
+2
source

I think the best thing to write here is:

 chomp(my $input = <STDIN>); 

Here is a brief example of how the chomp function (the meaning of $/ is explained here) deletes only one trailing newline (if any):

 chomp (my $input = "Me\n"); # OK chomp ($input = "Me"); # OK (nothing done) chomp ($input = "Me\n\n"); # $input now is "Me\n"; chomp ($input); # finally "Me" print "$input can be reached at $name_number{$input}\n"; 

BTW: It's funny that I also learn Perl, and five minutes ago I reached the hash.

0
source

While this may be obvious, it's still worth mentioning why chomp is required here.

The created hash contains 4 search keys: "Me" , "Home" , "Emergency" and "Lookup"

When $input is specified from <STDIN> , it will contain "Me\n" , "Me\r\n" or some other variant of line ending depending on the operating system used.

An uninitialized value error occurs because the key "Me\n" does not exist in the hash. And that is why chomp needed:

 my $input = <STDIN>; # "Me\n" --> Key DNE, $name_number{$input} not defined chomp $input; # "Me" --> Key exists, $name_number{$input} defined 
0
source

All Articles