2011-09-03 36 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/