六、子程序的引用
perl中子程序的引用与c中函数的指针类似,构造方法如下:
$pointer_to_sub = sub {... declaration of sub ...};
通过所构造的引用调用子程序的方法为:
&$pointer_to_sub(parameters);
·子程序模板
子程序的返回值不仅限于数据,还可以返回子程序的引用。返回的子程序在调用处执行,但却是在最初被创建的调用处被设置,这是由perl对closure处理的方式决定的。closure意即如果你定义了一个函数,它就以最初定义的内容运行。(closure详见oop的参考书)下面的例子中,设置了多个错误信息显示子程序,这样的子程序定义方法可用于创建模板。
#!/usr/bin/perl
sub errormsg {
my $lvl = shift;
#
# define the subroutine to run when called.
#
return sub {
my $msg = shift; # define the error type now.
print "err level $lvl:$msg\n"; }; # print later.
}
$severe = errormsg("severe");
$fatal = errormsg("fatal");
$annoy = errormsg("annoying");
&$severe("divide by zero");
&$fatal("did you forget to use a semi-colon?");
&$annoy("uninitialized variable in use");
结果输出如下:
err level severe:divide by zero
err level fatal:did you forget to use a semi-colon?
err level annoying:uninitialized variable in use
上例中,子程序errormsg使用了局域变量$lvl,用于返回给调用者。当errormsg被调用时,$lvl的值设置到返回的子程序内容中,虽然是用的my函数。三次调用设置了三个不同的$lvl变量值。当errormsg返回时,$lvl的值保存到每次被声明时所产生的子程序代码中。最后三句对产生的子程序引用进行调用时$msg的值被替换,但$lvl的值仍是相应子程序代码创建时的值。
很混淆是吗?是的,所以这样的代码在perl程序中很少见。
七、数组与子程序
数组利于管理相关数据,本节讨论如何向子程序传递多个数组。前面我们讲过用@_传递子程序的参数,但是@_是一个单维数组,不管你传递的参数是多少个数组,都按序存贮在@_中,故用形如my(@a,@b)=@_; 的语句来获取参数值时,全部值都赋给了@a,而@b为空。那么怎么把一个以上的数组传递给子程序呢?方法是用引用。见下例:
#!/usr/bin/perl
@names = (mickey, goofy, daffy );
@phones = (5551234, 5554321, 666 );
$i = 0;
sub listem {
my ($a,$b) = @_;
foreach (@$a) {
print "a[$i] = " . @$a[$i] . " " . "\tb[$i] = " . @$b[$i] ."\n";
$i++;
}
}
&listem(\@names, \@phones);
结果输出如下:
a[0] = mickey b[0] = 5551234
a[1] = goofy b[1] = 5554321
a[2] = daffy b[2] = 666
注意:
1、当想传递给子程序的参数是多于一个的数组时一定要使用引用。
2、一定不要在子程序中使用形如 (@variable)=@_; 的语句处理参数,除非你想把所有参数集中到一个长的数组中。
八、文件句柄的引用
有时,必须将同一信息输出到不同的文件,例如,某程序可能在一个实例中输出到屏幕,另一个输出到打印机,再一个输出到记录文件,甚至同时输出到这三个文件。相比较于每种处理写一个单独的语句,可以有更好的实现方式如下:
spitout(\*stdin);
spitout(\*lphandle);
spitout(\*loghandle);
其中子程序spitout的代码如下:
sub spitout {
my $fh = shift;
print $fh "gee wilbur, i like this lettuce\n";
}
注意其中文件句柄引用的语法为\*filehandle。
Java Asp PHP .Net XML C/C++ CGI VB Jsp J2ee J2se J2me EJB Servlet Tomcat Resin Struts Weblogic Eclipse ANT GUI JMS Web servise IDEA Webphere Hibernate Spring Jboss Applet Swing Socket Javamail Perl Ajax P2P 安全 模式 框架 测试 开源 游戏
Windows XP Windows 2000 Windows 2003 Windows Me Windows 9.x Linux UNIX 注册表 操作系统 服务器 应用服务器