Perl子例程(函数)
Perl子例程编程教程,例子教程,参考手册和代码 - 这两个术语可以在Perl函数和子程序互换使用。
这两个术语可以在Perl函数和子程序互换使用。函数是一个命名的代码块,通常是用于处理指定到的输出值的输入值,虽然这并不总是这样。例如,打印函数需要变量和静态文本,并打印在屏幕上的值。
- 像许多的其它语言,Perl提供了为用户自定义子程序。
- 这些可以位于在主程序中的任何地方。
- 通过从其他文件加载,要求(require),也可以使用关键字。
- 任何传入的参数显示在数组@_。
- return语句可用于退出子程序。
- 如果没有返回,如果最后的语句是一个表达式,那么就返回它的值。
- 如果最后语句是像一个foreach或while循环控制结构,返回的值是不确定的。
- 子程序可以返回标量,数组或哈希。
子程序,如变量,可以声明(不用定义他们来做了什么)或声明和定义。简单地声明一个子程序,可以使用下列形式之一:
sub NAME sub NAME PROTO sub NAME ATTRS sub NAME PROTO ATTRS
其中,NAME是您所创建的子程序的名称,Proto是期望的子程序调用时的参数的原型,ATTRS是一个属性的子程序呈现。
如果你想声明和定义一个函数,那么你就需要包括块定义其操作:
sub NAME BLOCK sub NAME PROTO BLOCK sub NAME ATTRS BLOCK sub NAME PROTO ATTRS BLOCK
您还可以创建匿名函数 - 没有名字的子程序省略NAME组件:
sub BLOCK sub PROTO BLOCK sub ATTRS BLOCK sub PROTO ATTRS BLOCK
要调用一个函数,你可以使用下列形式之一:
NAME NAME LIST NAME (LIST) &NAME
举一个简单的例子,一个简单的子程序:
sub message { print "Hello!\n"; # by www.yiibai.com }
函数参数
第一个参数传递给子程序是在函数的$_[0],第二个参数是$_[1]等等。这个简单的函数例如,将两个数相加并输出结果:
sub add { $result = $_[0] + $_[1]; print "The result was: $result\n"; }
要调用的子程序,得到的结果:
add(1,2);
前面的子程序是相当简单的,但如果你想已经命名参数吗? 简单的答案是指定的值@_的变量列表:
sub add { ($numbera, $numberb) = @_; $result = $numbera + $numberb; print "The result was: $result\n"; }
shift 函数是一个堆栈,操作数由Perl支持。shift 函数返回一个数组的第一个元素(删除)。例如:
sub add { my $numbera = shift; my $numberb = shift; #by www.yiibai.com my $result = $numbera + $numberb; print "The result was: $result\n"; }
效果是完全一样的,因为我们已经证明,但以不同的方式,我们刚刚得到的参数。
函数返回值
任何块的返回值,包括那些在子程序中使用,作为最后计算的表达式的值。 对于为例,这里的返回值是计算结果。
sub myfunc { $_[0]+$_[1]; }
您也可以显式地返回一个值,使用return关键字:
sub myfunc { if (@_) { return $_[0]+$_[1]; } else { return 0; } }
调用时,立即返回,而终止当前的子程序并返回值给调用者。如果你不指定一个值,则返回值是undef。
函数调用的上下文
一个子程序或语句的上下文中被定义为预期的返回值的类型。这使您可以使用一个单一的函数,返回不同的值,根据用户期望接收。例如,下面的两个调用的getpwent函数返回一个列表或一个标量,根据分配使用:
$name = getpwent(); ($name, $passwd, $uid, $gid, $quota, $comment, %gcos, $dir, $shell) = getpwent();
在第一种情况下,用户的期望由该函数返回一个标量值,因为返回值将被赋值。在第二种情况下,用户期望的阵列作为返回值再次由于已被指定为要插入到的信息的标量的列表。
下面是另一个例子,从内置Perl函数显示灵活性:
my $timestr = localtime(time);
在这个例子中,当前的日期和时间所组成的字串$timestr的值。例如,2000年11月30日15时21分33秒,星期四。相反的:
($sec,$min,$hour,$mday,$mon, $year,$wday,$yday,$isdst) = localtime(time);
现在,单个变量包含相应的值返回的本地时间。
左值子程序
注: 左值的子程序仍然是实验性的实施可能会在未来Perl版本中有所改变。
从子程序返回一个可修改的值是有可能的。要做到这一点,你必须声明的子程序返回一个左值。参见下面的例子
my $val; sub canmod : lvalue { # return $val; this doesn't work, don't say "return" $val; } sub nomod { $val; }
现在看到以下结果:
canmod() = 5; # assigns to $val in the above subroutine nomod() = 5; # ERROR
将列表传递给子程序
因为@_变量是一个数组,它可以被用来提供列表子程序。然而,因为在其中Perl接受并解析列表和数组的方式,它可以是难以提取从@_的单个元素。以下是有效的。
mysub(1,2,3); @args = (2,3); mysub(1,@args); @args = (1,2,3); mysub(@args);
最后,当我们收到的值@_变量,我们可以不承认如果我们通过一个数组或两个值数组,因为它最后要合并成一个。
如果你想使用并确定传递给Perl的个别列表,那么你需要使用参考:
(@listc, @listd) = simplesort(\@lista, \@listb);
开头的\字符告诉Perl提供参考,指针,数组的。 引用是实际上只是一个标量,因此,我们可以找出每个列表分配给每个阵列在我们的子程序。现在,你可以写子程序如下:
sub simplesort { my ($listaref, $listbref ) = @_; # De-reference the array list - by www.yiibai.com my (@lista) = @$listaref; my (@listb) = @$listbref; #by www.yiibai.com # Now you can play with both arrays. }