2013-11-15 84 views
2

我在學習Perl,並且我有2個關於如何完成相同任務的例子,我只是對寫腳本的方式感到困惑。Perl函數和子程序

腳本#1

#!/usr/bin/perl 
use strict; 
use warnings; 
use IO::File; 

my $filename = "linesfile.txt"; # the name of the file 

# open the file - with simple error reporting 

my $fh = IO::File->new($filename, "r"); 
if(! $fh) { 
print("Cannot open $filename ($!)\n"); 
exit; 
} 

# count the lines 
my $count = 0; 
while($fh->getline) { 
$count++; 
} 

# close and print 
$fh->close; 
print("There are $count lines in $filename\n"); 

腳本#2

#!/usr/bin/perl 
# 
use strict; 
use warnings; 
use IO::File; 

main(@ARGV); 

# entry point 
sub main 
    { 
    my $filename = shift || "linesfile.txt"; 
    my $count = countlines($filename); 
    message("There are $count lines in $filename"); 
    } 

# countlines (filename) - count the lines in a file 
# returns the number of lines 
sub countlines 
{ 
my $filename = shift; 
error("countlines: missing filename") unless $filename; 

# open the file 
my $fh = IO::File->new($filename, "r") or 
    error("Cannot open $filename ($!)\n"); 

# count the lines 
my $count = 0; 
$count++ while($fh->getline); 

# return the result 
return $count;  
} 

# message (string) - display a message terminated with a newline 
sub message 
{ 
    my $m = shift or return; 
    print("$m\n"); 
} 

# error (string) - display an error message and exit 
sub error 
{ 
    my $e = shift || 'unkown error'; 
    print("$0: $e\n"); 
    exit 0; 
} 

從腳本#2我不明白背後的以下

  1. 主(@ARGV)的目的;
  2. 爲什麼我們需要子消息和子錯誤?

由於

回答

3

目的是按照的職責分解代碼,使其更具可讀性,因此在未來更容易維護和擴展。 main函數用作明顯的入口點,message負責將消息寫入屏幕,而error用於寫入錯誤消息並終止程序。

在這種情況下,將一個簡單的程序拆分爲子程序的代價並不高,但第二個腳本很可能意味着作爲一個教學工具來展示一個程序如何構建。

3

@ARGV陣列是爲提供給腳本的參數的列表。例如當調用的腳本是這樣的:

./script.pl one two three 

@ARGV陣列將包含("one", "two", "three")

sub messagesub error子程序用於向用戶顯示信息。例如:

message("There are $count lines in $filename"); 
error("Cannot open $filename ($!)\n"); 

上面兩行稱爲這些子程序。這只是一個稍微好一點的告知用戶的方式,因爲可以對輸出進行一致的調整(例如爲消息添加時間戳或將其寫入文件)。

3

main(@ARGV);正在調用具有參數的主子例程,該參數是程序的 參數。 其他子程序用於具有可重用的代碼。將需要多次編寫相同的代碼,因此創建包含此代碼的子例程將非常有用。