sub marine{ $n += 1; print "Hello, sailor number $n!\n";}
在子程序中使用到全局变量,在程序的其它部分也可以使用。
调用子程序:&marine;
通常把调用子程序称为呼叫子程序。
子程序中最后一次运算的结果(不管是什么),都会被自动当成子程序到返回值。
要传递参数列表到子程序里,只要在子程序调用的后面加上被括号圈引的列表表达式就行了。
$n = &max(10,15);
参数列表在执行子程序的时候会将其存到数组变量@_中,该变量在子程序执行期间有效。子程序可以访问这个数组,以判断参数的个数以及参数的值。也就是第一个参数存储于$_[0],第二个参数存储于$_[1],依次类推,但请注意,这些变量和$_变量毫无关联,就像$dino[3]和$dino毫无关联一样。
sub max{ if($_[0] > $_[1]) $_[0];} else{ $_[1];}}
子程序中的私有变量:这些变量到作用范围被全定在语句块中,它们是该语句块到私有变量,其它地方的同名变量完全不受这两个私有变量的干扰。反之,别的程序代码也偶无法反问或修改这些私有变量,不管是无心或是有意。所以我们可以把这个自测很难工序放进世界上任何一个Perl程序里,且不用担心与那个程序中的变量发生冲突。
sub max{ my($m,$n) = @_; if($m > $n){ print "$m\n";} else{ print "$n\n";}}
参数数量可变的子程序,更好的&max子程序:
sub max{ my($max_so_far) = shift @_; foreach (@_){ if($_ > $max_so_far){ $max_so_far = $_;} } max_so_far;}
如果参数列表中参数为空,则返回undef。
词法变量my可以使用在任何块内,而不急限于子程序的语句块。且my操作符并不会更改变量赋值时的上下文:
my ($num) = @_; #列表上下文,和($num) = @_相同 my $num = @_; #标量上下文,和$nu = @_;相同,被设为参数的个数 在my不是用括号时,只用来声明单个词法变量: my $fred,$barney; #错!没生命$barney my($fred,$barney); #两个都声明了 my @phone_number; #声明私有数组use strict 编译命令,对编译器只是,告诉它关于程序代码的一些信息。使用该命令,会让Perl语法编译器,对当前语句块或源文件剩下的部分强制执行一些严格的,确保良好程序设计的规则。
该命令会要求你一定要用my来声明每个新的变量。
my bamm_bamm = 3; #新的词法变量
建议使用该命令。
return操作符会从子程序中立即返回某个值。
my @names = qw/fred barney betty dino wilma pebbles bamm-bam/; my $result = $which_element_is("dino", @names); sub which_element_is{ my($what,@array) = @_; foreach(0..$#array){ #数组@_中所有元素的下标 if($what eq $array[$_]){ return $_;} #一发现就提前返回 } -1; #没有找到符合条件的元素,return在这里可有可无 }return 立即返回某个值,而不要执行子程序的其余部分。只有返回发生在子程序的最后一行代码之前的时候,才需要使用return。
持久性的私有变量:使用state操作符来声明变量,我们可以在子程序的多次调用间保留变量的值,并将变量的作用域局限于子程序中。词法变量my不保留变量的值。
running_sum(5,6); running_sum(1..3); running_sum(4); sub running_sum{ state $sum = 0; state @numbers; foreach my $number(@_){ push @numbers, $number; $sum += $number;} say "The sum of (@numbers) is $sum"; }
但是在使用数组和哈希类型的state变量时,还是有一些轻微限制的。在Perl 5.10中,我们不能在列表上下文中初始化这两种类型的state变量:
state @array = qw(a b c); #错误
在列表上下文中初始化state变量是被禁止的。