2013-11-15 45 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);正在调用具有参数的主子例程,该参数是程序的 参数。 其他子程序用于具有可重用的代码。将需要多次编写相同的代码,因此创建包含此代码的子例程将非常有用。