Perl的子程序就是函数,注意Perl的子程序是不加括号的;所以,相应的,在Perl中向子程序传递参数也和别的编程语言不太一样(是不是很有趣 :)
Perl的子程序相当于别的语言的函数,使用关键字sub
标注
但是在语法上它更像是“可以传参数的代码块”(没有括号;可以传参)
sub sth{ # ``sub``是关键字,不能省略
...
}
sub average{
$n = scalar(@_);
$sum = 0;
foreach $item(@_){
$sum + = $item;
}
$average = $sum/$n;
print "The average is $average\n";
}
子程序调用的时候需要加括号,这一点和“定义时不加括号”要区分开来
average(10,20,30)"; # 20
值得注意的是,子程序中定义的任何变量都是全局的(除非用my
声明)
sub print_num{
$n=@_;
print "There are $n words inputed.\n";
}
print_sum(1, 2, 3); # There are 3 words inouted.
print "After the sub progress, the value of n is $n\n"; # After the sub progress, the value of n is 3(因为在子程序中定义的变量默认是全局的,所以n的值被前面的调用改变了!)
在Perl中,子程序对外输出信息即返回的方式有两种,
其中,一种是使用return
语句显式声明返回信息
# 子程序1
sum{
return $_[0]+$_[1];
}
# 调用1
print "sum(1,2)"; # 3
另一种可以直接把最后一句作为返回信息(Perl的特色写法)
# 子程序2
sum{
$_[0]+$_[1];
}
# 调用2
print "sum(3,4)"; # 7
结合不同的上下文,同一个子程序的返回值可以有不同的类型和意义
#!/usr/bin/perl
# 标量上下文
my $datestring = localtime( time );
print $datestring;
print "\n";
# 列表上下文
($sec,$min,$hour,$mday,$mon, $year,$wday,$yday,$isdst) = localtime(time);
printf("%d-%d-%d %d:%d:%d",$year+1990,$mon+1,$mday,$hour,$min,$sec);
print "\n";
# 输出
Sun Jun 12 15:58:09 2016
2106-6-12 15:58:9
在子程序内部所有被传入的参数其实都是列表
可以向子程序中传入列表或哈希,后者将被隐式转换为列表
对于标量,在子程序中可以通过列表下标获取
# 子程序3
sub print_array{
...
@array = @_;
print "The array is @array"l;
}
# 调用3
test_array = (1,2,3);
print_array(@arr); # 1 2 3
# 子程序4
sub print_hash{
...
my %hash = @_;
foreach my $key(keys %hash){
my $value = $hash{$key};
print "$key: $value\n";
}
}
# 调用4
%hash = ('name'=>'albert', 'age'=>34);
print_hash(%hash); # name: albert
# age: 34
默认情况下,Perl中所有的变量都是全局的
可以通过my
关键字声明一个变量为私有的
#!/bin/perl
# 全局变量
$string = "Hello, World!";
# 函数定义
sub PrintHello{
# PrintHello 函数的私有变量
my $string;
$string = "Hello, Perl!";
print "函数内字符串:$string\n";
}
# 调用函数
PrintHello();
print "函数外字符串:$string\n";
# 输出
函数内字符串:Hello, Perl
函数外字符串:Hello, world
可以使用local
关键字修饰全局变量,使其具有临时的值
该关键字的作用范围仅限于相应的代码块(通常是子程序),退出后失效
#!/usr/perl
# 全局变量
$string = "Hello, World!";
sub PrintRunoob{
# PrintHello 函数私有变量
local $string;
$string = "Hello, Runoob!";
# 子程序调用的子程序
PrintMe();
print "PrintRunoob 函数内字符串值:$string\n";
}
sub PrintMe{
print "PrintMe 函数内字符串值:$string\n";
}
sub PrintHello{
print "PrintHello 函数内字符串值:$string\n";
}
# 函数调用
PrintRunoob();
PrintHello();
print "函数外部字符串值:$string\n";
#输出
PrintMe 函数内字符串值:Hello, Runoob!
PrintRunoob 函数内字符串值:Hello, Runoob!
PrintHello 函数内字符串值:Hello, World!
函数外部字符串值:Hello, World!
和C语言的static
关键字类似,Perl使用state
关键字表明一个变量是静态的
静态变量具有文件作用域,且符合静态存储
Perl同样支持“局部静态变量”
#!/bin/perl
use feature 'state';
sub PrintCount{
state $count = 0; # 初始化变量
print "counter 值为:$count\n";
$count++;
}
for (1..3){
PrintCount();
}
# 输出
counter 值为:0
counter 值为:1
counter 值为:2
counter 值为:3
counter 值为:4
静态修饰符可以修饰“标量”、“列表”、“哈希”,但是却不能对“列表”或“哈希”初始化(至少在Perl5.x还不行~)