2011-09-03 37 views
7

我现在正在上课休息,并决定花时间学习Perl。我正在使用Beginning Perl(http://www.perl.org/books/beginning-perl/),并且在第三章结束时我将完成练习。我正在寻找关于chomp的一些澄清

其中一个练习题要求我“将重要的电话号码存储在一个散列表中,编写一个程序来查看该人的姓名。”

无论如何,我想出了这一点:

#!/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"; 

而且这是做不到的。我不断收到此错误信息:(。)在hello.plx 线17,第1行

使用未初始化值的串联或字符串我试图与代码玩弄一些,但每个“解决方案”看起来都比之前的“解决方案”复杂。最后,我决定检查答案。

我的代码和答案之间唯一的区别是在<STDIN>;之后出现chomp ($input);

现在,笔者在前面的例子中使用了chomp,但他并没有真正涵盖chomp正在做什么。所以,我发现www.perlmeme.org这样的回答:

chomp()功能将删除(通常)从 一个字符串的结尾任何换行符。我们通常说的原因是,它实际上 消除了换行是的$/(输入 记录分隔符)的当前值匹配任何字符,并$/默认..


不管怎样,我的问题是:

  1. 什么换行符被删除? Perl会自动将"\n"附加到来自<STDIN>的输入吗?我只是有点不清楚,因为当我读到“它实际上删除了与当前值$/相匹配的任何字符”时,我不禁想到“我不记得在我的代码中的任何地方放置$/”。

  2. 我想尽快开发最佳实践 - 是否最好在<STDIN>之后始终包含chomp或者是否存在不必要的情况?

+2

'的perldoc -f chomp'或[perlfunc(http://perldoc.perl.org/perlfunc.html) – 2011-09-03 00:59:35

+0

好了,所以在Perlmeme的FAQ(HTTP的格格条目: //www.perlmeme.org/faqs/manipulating_text/chomp.html)回答了我的第一个问题。也就是说,FAQ使我相信Perl会自动换行(不一定是“\ n”,而换行符也是一样)。但我能正确理解吗? – krebshack

+0

继续使用来自perlfunc:[chomp](http://perldoc.perl.org/functions/chomp.html)的链接,其中介绍了分隔符的使用。 – 2011-09-03 01:01:03

回答

9

<STDIN>读取到输入字符串,如果按回车键进入它包含一个换行符,这你可能做的结束。

chomp删除字符串末尾的换行符。 $/是一个变量(如您发现的,默认为换行符),您可能不必担心;它只是告诉perl什么'输入记录分隔符',我假设它意味着它定义了多远<FILEHANDLE>读取。你现在几乎可以忘记它,它似乎是一个高级话题。只需将chomp chomps伪装成尾随的换行符即可。老实说,我从来没有听说过$/之前。

至于你的其他问题,这是一般吸尘器总是终日啃食变量,并添加换行符随后需要的,因为你并不总是知道如果一个变量有一个换行符与否;通过总是咀嚼变量,你总会得到相同的行为。有些情况下,它是不必要的,但如果你不确定它不会伤害到chomp它。

希望这会有所帮助!

+1

将读取到输入字符串的末尾,如果按回车键输入字符串,则输入字符串将包含换行符,您可能会这样做。”这清理了很多。我不记得作者提到在输入之后按回车会自动包含一个换行符。虽然这解释了为什么即使我没有(明知)将代码写入代码,也会创建换行符。谢谢你的帮助。 – krebshack

+1

@kreb - 这不是真正的Perl专用 - 新行行为是特定于操作系统的(大多数操作系统都会这样做,尽管不同的操作系统有不同的换行符 - 这就是'$ /'进来的地方.Windows/DOS换行符不同于Unix换行符。对你来说幸运的是,Perl Just Works - 也就是说,Windows Perl会将'$ /'设置为Windows换行符。请参阅shawnhcorey在 – DVK

0

我认为最好的做法在这里是写:

chomp(my $input = <STDIN>); 

下面是简单的例子如何chomp功能($/含义有解释)的作品删除只是一个尾随新行(如果有的话):

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:有趣的是我也学习Perl,并在五分钟前达到了哈希。

+0

下面的出色答案哦,这很有趣。你使用了哪些资源?我发现访问as有帮助很多教程/书籍/网站尽我所能学习新东西 – krebshack

+0

@krebshack:我主要使用[Learning Perl](http://oreilly.com/catalog/0636920018452?green=c142e8ee-fefc-4f4d- 80d1-fb6d1f20e787&cmp = af-mybuy-0636920018452.IP)(来自[Safari Books](http://my.safaribooksonline.com/))和有时[perldoc](http://perldoc.perl.org/)。 –

+0

当我的下一个薪水到来时,我必须选择这个。除了积极的经历之外,我什么都没有与O'Reilly's合作。 – krebshack

3

行,如1),Perl并不在输入添加任何\n。输入完数字后,输入输入。如果您未指定$/,则会放置默认值\n(至少在UNIX下)。

作为2),将需要格格每当输入来自用户,或每当要删除行结束字符(从文件中读取,例如)。

最后,你得到的错误可能来自Perl不理解你最后print的双引号内的变量,因为它确实有_字符。尝试写入字符串如下:

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

(注意周围的最后一个变量的{})。

+0

我不确定。我试图用“打印”$输入...“字符串与”打印“”$输入可以达到$ {name_number {$输入}} \ n“;”当后跟chomp时,它返回相同的结果。当没有chomp时,它也返回相同的错误消息。但是,按照你演示的方式写字符串应该是我应该学习的一种习惯吗? – krebshack

+0

为什么double * double *引号?关于变量,是的,如果在双引号内,带有'_'等特殊字符的变量应该被'{}包围“。 –

+0

好的,很高兴知道。我将删除双引号。这是一个错字。 – krebshack

0

虽然可能很明显,但它仍值得一提为什么这里需要chomp

哈希创建包含4个查找关键字:"Me""Home""Emergency""Lookup"

当从<STDIN>指定$input,它会包含"Me\n""Me\r\n"或其他一些行结束变种取决于什么操作系统正在使用。

未初始化值错误出现有关,因为"Me\n"关键并不在散存在。这就是为什么需要chomp

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

<STDIN>readline(*STDIN);短切符号。 readline()所做的是读取文件句柄,直到遇到$ /(也就是$ INPUT_RECORD_SEPARATOR)的内容并返回它已读取的所有内容(包括$ /的内容)。 chomp()所做的是删除$ /的最后出现内容(如果存在)。

内容通常称为换行符,但它可能由多个字符组成。在Linux上,它包含一个LF字符,但在Windows上它包含CR-LF。

参见:

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