Perl精华教程

来源:互联网 发布:健康体检报告软件 编辑:程序博客网 时间:2024/05/21 11:15
Perl教程
第一讲
1、一个最简单的Perl程序 

  这里是我们开始的一个基本的perl程序:
#!/usr/local/bin/perl
#
# Program to do the obvious
#
print 'Hello world.';# Print a message

我们将对其中的每个部分进行讨论。
第一行:
每个perl程序的第一行都是:
#!/usr/local/bin/perl
- 虽然随着系统的不同而不同。这行告诉机器当文件执行时该怎么做(即告诉它通过Perl运行这个文件)。 
目 录 

第一讲
  1、一个最简单的Perl程序
  2、运行程序
  3、标量 
第二讲
  1、数组变量
  2、文件处理
  3、控制结构 
第三讲
  1、条件语句
  2、字符串匹配
  3、替换和翻译 
第四讲
  1、Split
  2、关联数组
  3、子过程 
其它网上教程-->>


注释和语句:

  用#符号可以在程序中插入注释,并且从#开始到这行结尾都被忽略(除了第一行)。把注释扩展到几行的唯一办法是在每行前都用#符号。
  Perl中的语句必须在结尾加一个分号,象上面程序中最后一行那样。

简单的打印:

  print函数输出一些信息。在上面的例子中它打印出字符串Hello world,当然这行也以分号结束。
  你可能会发现上面的程序会产生一个有点意想不到的结果,那么就让我们运行它吧。

  用文本编辑器敲入这个例子程序,然后保存之。Emacs是一个很好的编辑器,但是你可以使用任何习惯的文本编辑器。
  然后用下面的命令使这个文件可执行。
  chmod u+x progname

  在UNIX提示符下,progname是程序的文件名。现在可以运行这个程序 - 在提示符下运行下面任何一种命令:
perl progname ./progname progname
如果有错误,将会得到错误信息,或者什么也得不到。可以用warning参数运行程序:
perl -w progname
这会在试图执行程序前显示警告和其它帮助信息。用调试器运行程序可以使用命令:
perl -d progname
当执行程序时,Perl首先编译之,然后执行编译后的版本。于是在经过编辑程序后的短暂停顿后,这个程序会运行得很快。



2、运行程序

  用文本编辑器敲入这个例子程序,然后保存之。Emacs是一个很好的编辑器,但是你可以使用任何习惯的文本编辑器。
  然后用下面的命令使这个文件可执行。
  chmod u+x progname

  在UNIX提示符下,progname是程序的文件名。现在可以运行这个程序 - 在提示符下运行下面任何一种命令:
perl progname ./progname progname
如果有错误,将会得到错误信息,或者什么也得不到。可以用warning参数运行程序:
perl -w progname
这会在试图执行程序前显示警告和其它帮助信息。用调试器运行程序可以使用命令:
perl -d progname
当执行程序时,Perl首先编译之,然后执行编译后的版本。于是在经过编辑程序后的短暂停顿后,这个程序会运行得很快。>>



3、标量

  Perl中最基本的变量是标量。标量可以是字符串或数字,而且字符串和数字可以互换。例如,语句
$priority = 9;
设置标量$priority为9,但是也可以设置它为字符串:$priority = 'high';
Perl也接受以字符串表示的数字,如下:
$priority = '9'; $default = '0009';
而且可以接受算术和其它操作。
  一般来说,变量由数字、字母和下划线组成,但是不能以数字开始,而且$_是一个特殊变量,我们以后会提到。同时,Perl是大小写敏感的,所以$a和$A是不同的变量。

操作符和赋值语句:

  Perl使用所有的C常用的操作符:
$a = 1 + 2;# Add 1 and 2 and store in $a
$a = 3 - 4;# Subtract 4 from 3 and store in $a
$a = 5 * 6;# Multiply 5 and 6
$a = 7 / 8;# Divide 7 by 8 to give 0.875
$a = 9 ** 10;# Nine to the power of 10
$a = 5 % 2;# Remainder of 5 divided by 2
++$a;# Increment $a and then return it
$a++;# Return $a and then increment it
--$a;# Decrement $a and then return it
$a--;# Return $a and then decrement it

  对于字符串,Perl有自己的操作符:
$a = $b . $c;# Concatenate $b and $c
$a = $b x $c;# $b repeated $c times
  Perl的赋值语句包括:
$a = $b;# Assign $b to $a
$a += $b;# Add $b to $a
$a -= $b;# Subtract $b from $a
$a .= $b;# Append $b onto $a

  其它的操作符可以在perlop手册页中找到,在提示符后敲入man perlop。

互操作性:

  下面的代码用串联打印apples and pears:

$a = 'apples';
$b = 'pears';
print $a.' and '.$b;
最后的打印语句中应该只包含一个字符串,但是:
print '$a and $b';
的结果为$a and $b,不是我们所期望的。
不过我们可以用双引号代替单引号:
print "$a and $b";
双引号强迫任何代码的互操作,其它可以互操作的代码包括特殊符号如换行(/n)和制表符(/t)。

第二讲
1、数组变量 

  数组变量是标量的集合。数组变量与标量有相同的形式,除了其前缀为@符号。下面的语句把三个元素赋给数组变量@food,把两个元素赋给数组变量@music。
  数组通过以0开始的索引进行访问,方括号内为索引值。表达式
$food[2]返回的结果为ells。注意上式中为$,而不是@,因为其引用的是一个标量。 

数组赋值 

  在Perl中,相同的表达式在不同的上下文中会产生不同的结果。下面的第一个赋值语句引用了@music变量,所以结果与第二个赋值语句相同。
  这也是把元素加入数组的一种方式。一种更简洁的把元素加入数组的方式是: 
目 录 

第一讲
  1、一个最简单的Perl程序
  2、运行程序
  3、标量 
第二讲
  1、数组变量
  2、文件处理
  3、控制结构 
第三讲
  1、条件语句
  2、字符串匹配
  3、替换和翻译 
第四讲
  1、Split
  2、关联数组
  3、子过程 
其它网上教程-->>


push(@food,"eggs");
- 把eggs推入数组@food的结尾。把两个或更多元素推入数组可以用下面方式中的一种:
push(@food, "eggs", "lard");
push(@food, ("eggs", "lard"));
push(@food, @morefood);
  push函数返回新的列表的长度。
  可以用pop函数移去一个列表中的最后一个元素,然后返回这个元素。在最初的列表中,pop函数返回eels,然后@food中有两个元素:
$grub = pop(@food); # Now $grub = "eels"
  也可以把数组赋给一个标量。通常上下文是很重要的。$f=@food;得到@food的长度,但是$f="@food";把列表转换成以空格隔开每个元素的字符串。通过改变特殊变量$"的值可以把空格用其它任何字符串代替。这个变量只是Perl中很多特殊变量中的一个,它们中的很多都有奇怪的名字。
  数组也可以用来为多个标量进行赋值:
($a, $b) = ($c, $d);# Same as $a=$c; $b=$d;
($a, $b) = @food;# $a and $b are the first two
# items of @food.
($a, @somefood) = @food;# $a is the first item of @food
# @somefood is a list of the
# others.
(@somefood, $a) = @food;# @somefood is @food and
# $a is undefined.
  最后一个赋值语句的发生是因为数组是贪婪的,@somefood会吞掉@food中的任何值。因此应尽量避免这种方式。
  最后,你可能想知道列表中最后一个元素的索引值,可以用这个表达式:$#food。

打印数组:

  既然上下文很重要,就不要奇怪下面的表达式产生不同的结果:
print @food;# By itself
print "@food";# Embedded in double quotes
print @food."";# In a scalar context



2、文件处理

  下面是一个简单的perl程序,与UNIX中cat命令对某个文件的操作相同。
#!/usr/local/bin/perl
#
# Program to open the password file, read it in,
# print it, and close it again.
$file = '/etc/passwd';# Name the file
open(INFO, $file);# Open the file
@lines = <INFO>;# Read it into an array
close(INFO);# Close the file
print @lines;# Print the array
  open函数打开一个文件并进行读操作。第一个参数filehandle是指向文件的句柄。第二个参数为被打开的文件的文件名。如果文件名以被引号包围的形式给出,那么它只被从字面意义上引用,而没有shell解释。
  因此表达式'~/notes/todolist'不会被成功地翻译。如果希望得到shell解释,可以使用尖括号:即使用<~/notes/todolist>。
  close函数告诉Perl关闭被打开的文件。
  open语句也可以对文件进行输出和附加操作。可以在文件名前加>进行输出操作,用>>进行附加操作:
open(INFO, $file);# Open for input
open(INFO, ">$file");# Open for output
open(INFO, ">>$file");# Open for appending
open(INFO, "<$file");# Also open for input
  如果想在一个已经打开的文件中打印信息,可以用带参数的打印语句。把一个字符串打印到一个用INFO句柄打开的文件中可以使用
print INFO "This line goes to the file./n";
可以用下面的语句打开标准输入(通常为键盘)和标准输出(通常为屏幕):
open(INFO, '-');# Open standard input
open(INFO, '>-');# Open standard output
  在上面的程序中从一个文件中读取信息。这个文件是INFO,Perl用尖括号对它进行读操作。因此语句
@lines=<INFO>;
  把文件中的所有信息读入数组@lines中。如果用标量$lines,则只读第一行。在这两种情况下,每行都以换行符结束。



3、控制结构

  Perl支持很多种与C类似的控制结构,但是也与Pascal很相似。下面我们分别对着这些结构进行讨论。
foreach
Perl使用foreach结构对数组或其它列表结构中的每行进行操作:
foreach $morsel (@food)# Visit each item in turn
# and call it $morsel
{
print "$morsel/n";# Print the item
print "Yum yum/n";# That was nice
}

  每次的操作过程被包围在花括号内。程序块中的$morsel第一次被赋予@food数组中的第一个值,然后被赋予数组的第二个值,依次类推。如果@food是空的,那么程序块将不会被执行。

判断

  判断是检验表达式结果是真是假的一种结构。在Perl中,任何非0数字和非空字符串被看作真。数字0、0字符串和空字符串被看作假。下面是一些基于数字和字符串的判断:
$a == $b# Is $a numerically equal to $b?
# Beware: Don't use the = operator.
$a != $b# Is $a numerically unequal to $b?
$a eq $b# Is $a string-equal to $b?
$a ne $b# Is $a string-unequal to $b?
也可以用逻辑与、或、非:
($a && $b)# Is $a and $b true?
($a || $b)# Is either $a or $b true?
!($a)# is $a false?
for
Perl的for结构与C的类似:
for (initialise; test; inc)
{
first_action;
second_action;
etc
}
语句initialise被首先执行,然后当test为真时程序块被执行。程序块每执行一次,inc发生一次。下面是一个循环打印数字0到9的循环:
for ($i = 0; $i < 10; ++$i)# Start with $i = 1
# Do it while $i < 10
# Increment $i before repeating
{
print "$i/n";
}

while和until
  下面是一个从键盘读输入,知道口令正确为止的程序:
#!/usr/local/bin/perl
print "Password? ";# Ask for input
$a = <STDIN>;# Get input
chop $a;# Remove the newline at end
while ($a ne "fred")# While input is wrong...
{
print "sorry. Again? ";# Ask again
$a = <STDIN>;# Get input again
chop $a;# Chop off newline again
}
  当键盘输入与口令不同时花括号内的程序块被执行。while结构很清晰,但有几点要注意:第一,我们可以从标准输入读入信息,而不用打开文件。第二,当口令被输入时,$a被赋予包括换行符在结尾的值。chop函数删除字符串的最后一个字符,这里是换行符。
  until也可以执行相同的工作。程序块被反复执行,直到表达式为真。
  另一种方式是把while或until放在程序块的后面。这要求do放在程序块的开始处,而判断在结尾处。这样程序可以这样写:
#!/usr/local/bin/perl
do
{
"Password? ";# Ask for input
$a = <STDIN>;# Get input
chop $a;# Chop off newline
}
while ($a ne "fred")# Redo while wrong input

第三讲
1、条件语句 

  Perl当然也支持if/then/else语句,下面是一个例子:
if ($a)
{
print "The string is not empty/n";
}
else
{
print "The string is empty/n";
}

  记住,空字符串被认为是false,如果$a是字符串"0",结果将是"empty"。 

  条件语句中也可以使用elsif: 
目 录 

第一讲
  1、一个最简单的Perl程序
  2、运行程序
  3、标量 
第二讲
  1、数组变量
  2、文件处理
  3、控制结构 
第三讲
  1、条件语句
  2、字符串匹配
  3、替换和翻译 
第四讲
  1、Split
  2、关联数组
  3、子过程 
其它网上教程-->>


if (!$a)# The ! is the not operator
{
print "The string is empty/n";
}
elsif (length($a) == 1)# If above fails, try this
{
print "The string has one character/n";
}
elsif (length($a) == 2)# If that fails, try this
{
print "The string has two characters/n";
}
else# Now, everything has failed
{
print "The string has lots of characters/n";
}
注意:elsif中确实缺一个"e"。



2、字符串匹配

  Perl的最有用的特征之一是它的强大的字符串处理能力。其中的核心是被很多其它UNIX工具使用的规则表达式(regular expression - RE)。

规则表达式

  规则表达式包含在斜线内,匹配通过=~操作符进行。如果字符串the出现在变量$sentence中,则下面的表达式为真:
$sentence =~ /the/
  RE是大小写敏感的,所以如果
$sentence = "The quick brown fox";
那么上面的匹配结果为false。操作符!~用在“非匹配”时,在上面的例子中
$sentence !~ /the/
是真,因为字符串the没有出现在$sentence中。

特殊变量$_

在条件语句
if ($sentence =~ /under/)
{
print "We're talking about rugby/n";
}
中,如果我们有下面两个表达式中的一个:
$sentence = "Up and under";
$sentence = "Best winkles in Sunderland";
将打印出一条信息。
  但是如果我们把这个句子赋值给特殊变量$_,用起来会更容易些。如果这样,我们可以避免使用匹配和非匹配操作符,上面的例子可以写成:
if (/under/)
{
print "We're talking about rugby/n";
}
  $_变量是很多Perl操作的缺省变量,经常被使用。

其它的RE

  在RE中有大量的特殊字符,既使它们功能强大,又使它们看起来很复杂。最好在用RE时慢慢来,对它们的使用是一种艺术。
  下面是一些特殊的RE字符和它们的意义:
.   # Any single character except a newline
^   # The beginning of the line or string
$   # The end of the line or string
*   # Zero or more of the last character
+   # One or more of the last character
?   # Zero or one of the last character

下面是一些匹配的例子,在使用时应加上/.../:

t.e   # t followed by anthing followed by e
    # This will match the
    # tre
    # tle
    # but not te
    # tale
^f   # f at the beginning of a line
^ftp  # ftp at the beginning of a line
e$   # e at the end of a line
tle$  # tle at the end of a line
und*  # un followed by zero or more d characters
    # This will match un
    # und
    # undd
    # unddd (etc)
.*   # Any string without a newline. This is because
    # the . matches anything except a newline and
    # the * means zero or more of these.
^$   # A line with nothing in it.

  还有更多的用法。方括号用来匹配其中的任何一个字符。在方括号中"-"表明"between","^"表示"not":
[qjk]   # Either q or j or k
[^qjk]   # Neither q nor j nor k
[a-z]   # Anything from a to z inclusive
[^a-z]   # No lower case letters
[a-zA-Z]  # Any letter
[a-z]+   # Any non-zero sequence of lower case letters

  上面提到的已经基本够用了,下面介绍的只做参考:
竖线"|"表示"or",括号(...)可以进行集合:
jelly|cream  # Either jelly or cream
(eg|le)gs   # Either eggs or legs
(da)+     # Either da or dada or dadada or...

  下面是一些其它的特殊字符:
/n   # A newline
/t   # A tab
/w   # Any alphanumeric (word) character.
    # The same as [a-zA-Z0-9_]
/W   # Any non-word character.
    # The same as [^a-zA-Z0-9_]
/d   # Any digit. The same as [0-9]
/D   # Any non-digit. The same as [^0-9]
/s   # Any whitespace character: space,
    # tab, newline, etc
/S   # Any non-whitespace character
/b   # A word boundary, outside [] only
/B   # No word boundary

  象$, |, [, ), /, /这样的字符是很特殊的,如果要引用它们,必须在前面加一个反斜线:
/|   # Vertical bar
/[   # An open square bracket
/)   # A closing parenthesis
/*   # An asterisk
/^   # A carat symbol
//   # A slash
//   # A backslash

RE的例子

  我们前面提到过,用RE最好慢慢来。下面是一些例子,当使用它们时应方在/.../中。

[01]   # Either "0" or "1"
//0   # A division by zero: "/0"
// 0   # A division by zero with a space: "/ 0"
///s0  # A division by zero with a whitespace:
     # "/ 0" where the space may be a tab etc.
// *0  # A division by zero with possibly some
     # spaces: "/0" or "/ 0" or "/ 0" etc.
///s*0  # A division by zero with possibly some
     # whitespace.
///s*0/.0*# As the previous one, but with decimal
      # point and maybe some 0s after it. Accepts
      # "/0." and "/0.0" and "/0.00" etc and
      # "/ 0." and "/ 0.0" and "/ 0.00" etc.



3、替换和翻译

  Perl可以在匹配的基础上进行替换操作。可以用s函数实现这个功能。如果不使用匹配操作符,那么替换被认为对$_变量进行操作。
  在字符串$sentence中用London替换london可以用下面的表达式:
$sentence =~ s/london/London/
用$_变量可以这样做:
s/london/London/
表达式的结果是替换发生的次数,所以或者是0或者是1。

选项

  上面的例子只替代第一个匹配的字符串,用g参数可以进行全程替换:
s/london/London/g
返回的结果为0或被替换的次数。
  如果我们想替换lOndon, lonDON, LoNDoN等,可以这样做:
s/[Ll][Oo][Nn][Dd][Oo][Nn]/London/g
但是可以有更简单的方式 - 使用i选项(忽略大小写):
s/london/London/gi

记忆方式

  如果记住匹配方式,以后用起来可以更方便。任何发生在括号内的匹配被记在变量$1,...,$9中。这些用在相同RE中的字符串可以用/1,...,/9表示:
$_ = "Lord Whopper of Fibbing";
s/([A-Z])/:/1:/g;
print "$_/n";
  这段代码替换任何大写字母为被冒号包围的形式。结果是:L:ord :W:hopper of :F:ibbing。变量$1,...,$9是只读变量,不可以修改它们。
另一个例子,判断语句:
if (/(/b.+/b) /1/)
{
print "Found $1 repeated/n";
}
将判断任何重复的单词。每个/b代表一个单词边界,.+与任何非空字符串相匹配,因此/b.+/b匹配任何两个单词边界中的内容。然后被括号记住,存储在/1中,$1被程序的其余部分使用。
  下面的表达式交换$_变量的第一个和最后一个字符:
s/^(.)(.*)(.)$//3/2/1/
^和$匹配行的开始和结尾。/1存储第一个字符,/2存储除第一个和最后一个字符之外的部分,最后一个字符存储在/3中。然后/1和/3进行互换。
  匹配之后,可以使用特殊的只读变量$~、$&和$'找到查询之前、之中和之后的内容。所以在
$_ = "Lord Whopper of Fibbing";
/pp/;
之后,下面的表达式都为真(eq表示字符串匹配判断)。
$` eq "Lord Wo";
$& eq "pp";
$' eq "er of Fibbing";
在替换表达式中可以使用变量,因此
$search = "the";
s/$search/xxx/g;
将把任何出现的the替换为xxx。如果想替换there,则不能使用s/$searchre/xxx/,因为程序会把它当作变量$searchre。可以用花括号实现there的替换:
$search = "the";
s/${search}re/xxx/;

翻译

  tr函数实现字符对字符的翻译。下面的表达式替换变量$sentence中的每个a为e,b为d,c为f。表达式返回替换的次数。
$sentence =~ tr/abc/edf/
  大多数特殊RE代码不能用在tr函数中。例如,下面的语句计算$sentence变量中的星号数,然后存储在变量$count中。
$count = ($sentence =~ tr/*/*/);
但是"-"仍然表示"between"。下面的语句把变量$_转换为大写形式:
tr/a-z/A-Z/;

第四讲
1、Split 

  Perl中的一个非常有用的函数是split - 把字符串进行分割并把分割后的结果放入数组中。这个函数使用规则表达式(RE),如果未特定则工作在$_变量上。
  split函数可以这样使用:
$info = "Caine:Michael:Actor:14, Leafy Drive";
@personal = split(/:/, $info);
其结果是:
@personal = ("Caine", "Michael", "Actor", "14, Leafy Drive");
  如果我们已经把信息存放在$_变量中,那么可以这样:
@personal = split(/:/);
如果各个域被任何数量的冒号分隔,可以用RE代码进行分割:
$_ = "Capes:Geoff::Shot putter:::Big Avenue";
@personal = split(/:+/); 
目 录 

第一讲
  1、一个最简单的Perl程序
  2、运行程序
  3、标量 
第二讲
  1、数组变量
  2、文件处理
  3、控制结构 
第三讲
  1、条件语句
  2、字符串匹配
  3、替换和翻译 
第四讲
  1、Split
  2、关联数组
  3、子过程 
其它网上教程-->>


其结果是
@personal = ("Capes", "Geoff", "Shot putter", "Big Avenue");
但是下面的代码:
$_ = "Capes:Geoff::Shot putter:::Big Avenue";
@personal = split(/:/);
的结果是
@personal = ("Capes", "Geoff", "", "Shot putter", "", "", "Big Avenue");

  单词可以被分割成字符,句子可以被分割成单词,段落可以被分割成句子:
@chars = split(//, $word);
@words = split(/ /, $sentence);
@sentences = split(//./, $paragraph);

  在第一句中,空字符串在每个字符间匹配,所以@chars数组是一个字符的数组。



2、关联数组

  顺序表数组允许我们按照数字对其元素进行访问。数组@food的第一个元素是$food[0],第二个元素是$food[1],等等。但是Perl也允许我们建立可以通过字符串进行访问的数组,称为关联数组(associative arrays)。
  我们用括号定义关联数组,但是数组名前有一个%符号。假设我们建立一个关于人和他们的年龄的数组,则可以这样:
%ages = ("Michael Caine", 39,
"Dirty Den", 34,
"Angie", 27,
"Willy", "21 in dog years",
"The Queen Mother", 108);
现在我们可以这样找到人们的年龄:
$ages{"Michael Caine"};# Returns 39
$ages{"Dirty Den"};# Returns 34
$ages{"Angie"};# Returns 27
$ages{"Willy"};# Returns "21 in dog years"
$ages{"The Queen Mother"};# Returns 108
访问单个元素时用$,而不是% - 因为单个元素是标量。关联数组的索引包含在花括号内。
  可以通过把关联数组赋给一个表数组变量把关联数组转换为表数组。表数组也可以转换为关联数组 - 通过把它赋值给关联数组变量。理想地,表数组将有偶数个元素:
@info = %ages;# @info is a list array. It
# now has 10 elements
$info[5];# Returns the value 27 from
# the list array @info
%moreages = @info;# %moreages is an associative
# array. It is the same as %ages

操作符

  关联数组的元素没有顺序(有点象hash表),但是可以通过keys函数和values函数轮流访问所有的元素:
foreach $person (keys %ages)
{
print "I know the age of $person/n";
}
foreach $age (values %ages)
{
print "Somebody is $age/n";
}
  当keys被调用时,返回关联数组的keys的列表。当values被调用时,返回数组的值的列表。这两个函数返回的列表的顺序相同,但是这个顺序与元素被输入的顺序没有关系。
  当keys和values在一个标量环境中被调用时,它们返回关联数组中的key/value对的数目。
  有一个each函数返回一个关键字和其值的两个元素的列表。每调用each一次,它返回另一个key/value对:
while (($person, $age) = each(%ages))
{
print "$person is $age/n";
}

环境变量

  当在UNIX中运行perl程序或任何script时,会遇到某些环境变量。比如,USER包含你的用户名,DISPLAY确定图形使用的屏幕。当在WWW中运行perl CGI script时,也有环境变量存储其它有用的信息。所有这些变量和它们的值存储在关联数组%ENV中,其关键字为变量名。可以试试这个perl程序:
print "You are called $ENV{'USER'} and you are ";
print "using display $ENV{'DISPLAY'}/n";



3、子过程

  和很多语言一样,Perl允许用户定义自己的函数,称为子过程(subroutine)。它们可以放在程序的任何地方,但是最好把它们全放在程序的顶部或尾部。
  子过程的形式如下:
sub mysubroutine
{
print "Not a very interesting routine/n";
print "This does the same thing every time/n";
}
  可以给子过程传递任何数量的参数。下面的语句都可以调用这个子过程。注意子过程在调用时在名称前使用一个&字符:
&mysubroutine;# Call the subroutine
&mysubroutine($_);# Call it with a parameter
&mysubroutine(1+2, $_);# Call it with two parameters

参数

  在上面的例子中参数被接受但是被忽略。当子过程被调用时,任何参数都被传递到特殊表数组变量@_中,这个变量与$_没有任何关系。下面的子过程只是打印它被调用的参数的列表。后面是一些调用它的例子。
sub printargs
{
print "@_/n";
}
&printargs("perly", "king");# Example prints "perly king"
&printargs("frog", "and", "toad"); # Prints "frog and toad"
  和任何其它列表数组一样,@_中的单个元素可以通过方括号访问:
sub printfirsttwo
{
print "Your first argument was $_[0]/n";
print "and $_[1] was your second/n";
}
要注意的是标量$_[0]和$_[1]等与标量$_没有任何关系。

返回值

  子过程的结果总是最后被赋值。下面的子过程返回其两个输入参数中较大的,然后是一个调用这个子过程的例子。
sub maximum
{
if ($_[0] > $_[1])
{
$_[0];
}
else
{
$_[1];
}
}

$biggest = &maximum(37, 24);# Now $biggest is 37

  上面的&printfirsttwo子过程也返回一个值,这时是1。这是因为这个子过程所做的最后一件事是print语句,打印成功的结果总是1。

局部变量

  @_变量对当前子过程是局部的,当然$_[0]、$_[1]、$_[2]等也是这样。其它变量也可以被设置为局部的,这在我们开始改变输入参数时是有用的。下面的子过程判断一个字符串是否在另一个中,不包括空格。然后是一个引用它的例子。

sub inside
{
local($a, $b);# Make local variables
($a, $b) = ($_[0], $_[1]);# Assign values
$a =~ s/ //g;# Strip spaces from
$b =~ s/ //g;# local variables
($a =~ /$b/ || $b =~ /$a/);# Is $b inside $a
# or $a inside $b?
}

&inside("lemon", "dole money");# true

  实际上,可以简化为
local($a, $b) = ($_[0], $_[1]);
原创粉丝点击