|
如果子程序larger_of_fred_barney 不是必须使用全局变量$fred 和$barney,那将变得更有用。如果要得到$wilma 和$betty 中
较大的值,现在必须将将它们的值拷贝到$fred 和$barney 中,然后再调用large_of_fred_or_barney。如果不希望改变这些变
量的值,那首先必须把这些变量拷贝到其它变量之中,如$save_fred 和$save_barney。然后,当子程序结束时,再把它们拷
贝回变量$fred 和$barney。
幸运的是,Perl 子程序可以带参数。将参数列表传给子程序中的方法是,在程序名后面接括号,括号内存放参数列表,如:
$n = &max(10,15); #此子程序有2 个参数
此参数列表被传到子程序中;这些参数可以被子程序使用。当然,这些参存放在某个地方,在Perl 中,会自动将此参数列
表(此参数列表的另一个名字)自动存放在一个叫做@_的数组中。子程序可以访问次数组变量来确定此参数的个数以及
其值。
这也就是说此子程序参数的第一个值存放在$_[0]中,第二个存放在$_[1],依次类推。但必须强调的是这些变量和$_这个
变量没有任何关系,如$dino[3](数组@dino 的一个元素)和$dino 的关系一样。这些参数必须存放在某个数组变量中,而Perl
存放在@_这个变量中。
现在,可以写子程序$max,其功能类似于&larger_of_fred_or_barney,但不是使用$fred,而使用($_[0]);不使用$barney,
而使用($_[1])。因此可以如下这些写代码:
sub max{
#和&larger_of_fred_or_barney 比较
If($_[0] > $_[1]){
$_[0];
}else{
$_[1];
}
}
我们说,你可以这样做。但使用这些下标有些难看,并且难于阅读,书写,检查,调试等。后面有更好的方法。
这个子程序有另一个问题。&max 这个名字很简单,但当调用的参数不是两个时,此程序不能提示出了错误:
$n = &max(10,15,27); #oops!
额外的参数被忽略了;因为此子程序不会使用$_[2],Perl 不会关心是否有多余的变量。参数不够时也会被忽略,当传入的
参数个数不够时,不够的参数会得到undef 这个值。在本章后面,将会有更好的方法,它可以在参数个数任意的情况下正
常工作。
@_是子程序的一个私有变量◆;如果有一个全局变量@_,它将在此子程序调用前存储起来,当子程序调用完成后,其早
期的值会被重新赋还给@_◆。这意味着当将参数传递给子程序时不用担心它会影响此程序中其它子程序的@_这个变量的
值。嵌套的子程序调用时,@_的值和上述类似。甚至此子程序递归调用时,每一次调用将得到新的@_,因此子程序调用
时将得到其自身的参数列表。
◆除非调用的子程序前有&而后面没有括号(或者没有参数),此时@_从此调用者的上下文(context)得到。这通常不是个好主意,但有时很
有用。
◆你可能意识到这里使用的机制和上一章中foreach 循环是一样的。在每种情况下,变量值被Perl 自动保存和重新赋值。 |
|