同标量和列表一样,子程序也有独立的名字空间,这样Perl就不会将同一段代码中的子程序&fred和标量$fred搞混了。
定义和调用子程序
sub marine { $n += 1; #全局变量 $n print "Hello, sailor number $n!\n"; } &marine(); #调用子程序
如果你定义了两个重名的子程序,那么后面的子程序会覆盖掉前面的那个。
调用子程序时的&号是可以省略的——如果编译器在调用子程序时看到过子程序的定义,或者Perl通过语法规则判断它只能是子程序调用,那么对待该子程序就可以像内置函数那样,调用时省略与号。有一个例外,加入这个子程序与Perl内置函数同名,为了避免歧义,必须使用与号。
所以真正的省略规则如下:除非你知道Perl所有的内置函数名,否则请务必在调用函数时使用与号。
注意:
1. 子程序中所有的变量都是全局的,除非用"my"修饰符声明是私有变量。
2. 所有的子程序都有返回值,即最后一次运算的结果;返回值可以为标量,也可以是列表。
参数列表
除了使用全局变量,子程序可以有自己的参数。Perl会自动将参数列表化名为特殊的数组变量"@_",该变量在子程序的私有变量。(加入已经有了全局变量@_,则该变量在子程序调用前会被存起来,并在子程序返回时恢复原本的值)
在真实的Perl代码中,常常把任意长度的列表作为参数传递给子程序。如果传入参数的个数不正确怎么办呢?可以通过检查@_的长度来判断是否正确——但在实际编写Perl程序中这种检查方式很少见,更好的做法是让子程序自动适应任意数目的参数。
关于词法(my)变量
词法变量可使用在任何语句块内,而不仅限于子程序的语句块。比如说,它可以在if、while、或foreach的语句块里使用:词法变量可使用在任何语句块内,而不仅限于子程序的语句块。比如说,它可以在if、while、或foreach的语句块里使用:
foreach (1..10) { my($square) = $_ * $_; print "$_ squared is $square.\n"; }
有经验的程序员都知道(这往往是付出惨痛代价换来的),将变量作用域圈定在一页或少数几行代码内,的确可以加快开发及测试周期。
持久性私有变量
使用state操作符声明的变量,我们可以在子程序多次调用期间保留变量之前的值,并将变量的作用域限于子程序内部。
use strict编译指令
Perl是一门相当宽容的编程语言,但也许你希望Perl能更加严格一些。"use strict"编译指令是要告诉Perl内部的编译器接下来的代码应该严谨一些,遵循一些优良的编程风格。
如果你在程序写完后再加"use strict",通常会得到一大堆警告信息;因此如果有需要,最好在开始写程序时就用它。