关于词法(my)变量:
事实上,词法可以不仅仅可以使用在子程序中,也可以在if、while、foreach当中。
foreach (1..10) { my($square) = $_ * $_; print "$_ squared is $square.\n"; } results: 1 squared is 1. 2 squared is 4. 3 squared is 9. 4 squared is 16. 5 squared is 25. 6 squared is 36. 7 squared is 49. 8 squared is 64. 9 squared is 81. 10 squared is 100.
my($num) = @_; #列表上下文,和($num) = @_;相同,$num会被设为第一个参数
my $num = @_; #标量上下文,和$num = @_;相同,$num会被设为参数个数
my $fred, $barney #$barney没有被声明
my($fred,$barney); #两个都声明了
my @phone_number;
|
use strict 编译命令:
Perl通常是一相当宽容的语言。但是,也许你会想要Perl更严格一些,这时只要使用use strict编译命令就行了。
编译命令(pragma),就是对编译器指示,告诉它关于程序代码的一些信息。use strict会让Perl语法编译强制执行
一些严格的、确保良好程序设计的规则。
$bamm_bamm = 3; #Perl会自动创建这个变量
$bammbamm += 1; #糟了!
因为Perl看到了一个新的变量名(变量名中的下划线是有意义的),它会创建一个新的变量。然后增加它的值。
如果你有先见之明,已经启用了warning的警告功能。那么Perl就会警告你这两个全局变量在程序中只出现过一次。
如果开启了use strict这个编译命令放在程序开头,Perl要求你一定要用my来声明每一个新的变量。
my $bamm_bamm = 3; #新的词法变量
现在,如果你再像之前那样拼错变量名,Perl就会抗议,说你从未声明$bammbamm这个变量,因此,错误在编译阶段就会被
找出来
$bammbamm += 1; #没有这个变量,这会是编译时严重错误(fatal error)
此限制只适用于新创建的变量;Perl的内置变量(如$_和@_)则完全不用事先声明。如果你在程序已经写完之后再加use strict,通常会得到一大堆警告信息,所以如果有需要,最好在一开始写程序时就使用它。
根据大部分人的建议,比整个屏幕长的程序都应该加上use strict。
return 操作符:
return操作符会从子程序中立即返回某个值:
my @names = qw/ fred barney betty dino wilma pebbles bamm-bamm /; my $result = &which_element_is ("dino", @names);
sub which_element_is { my ($what, @array) = @_; foreach (0..$#array) { #数组@array 中所有元素的下标
if ($what eq $array[$_]) { return $_; #一发现就提前返回
} } -1; #没找到符合条件的元素(return在这里可有可无)
}
|
上面程序里,&which_element_is子程序被用来找出"dino"在数组@names中的下标值。首先,我们会用my声明参数名:我们要找的$what,以及供程序搜索的数组@array。本例中,@array将会是数组@names的拷贝。foreach循环将会利用下标值逐项处理@array(第一个下标值是0,最后一个下标值是$#array)
省略”与号“
如果编译器在调用子程序之前看到了子程序的定义,或者Perl可以从语法识别它是子程序调用,那么该子程序就可以像内置
函数那样,在调用时省略”与号“。
假如Perl单从语法上便能看出它是省略了”与号“的子程序调用,通常就不会有什么问题。也就是说你只要将参数列表放进括号里,它就一定是函数。
my @cards = shuffle(@deck_of_cards); #shuffle前没必要用&
sub division { $_[0] /$_[1]; } my $quotient = division 355, 113; #使用&division
假如子程序和Perl内置函数同名,就必须使用"与号"来调用。配合”与号“,才可以正确调用子程序。 sub chomp { print "Munch, much!\n"; } &chomp; #这里必须使用&,绝对不能省略!
非标量返回值: 子程序不仅可以返回标量值,如果你在列表上下文中调用它,它就能返回列表值。 假设你想取出某段范围的数字(如同范围操作符..的递增序列)只是你不但想递增,还想要递减序列。虽然范围操作符只能产生递增序列,不过要反过来取也不是什么难事:
sub list_from_fred_to_barney { if ($fred < $barney) { #从$fred 数到$barney
$fred..$barney; } else { #从$fred倒数回$barney
reverse $barney..$fred; } } $fred = 11; $barney = 6 ; @c = &list_from_fred_to_barney; #@c的值为(11,10,9,8,7,6)
持久性私有变量: 在子程序中可以使用my操作符来创建私有变量,但每次调用这个子程序的时候,这个私有变量都会被得新定义。使用state操作符来声明变量,便可以在子程序的多次调用间保留变量的值。
use 5.010; sub marine { state $n = 0; #持久性私有变量 $n
$n += 1; #全局变量$n
print "Hello, sailor number $n!\n"; } ================================================== use 5.010;
running_sum( 5, 6); running_sum( 1..3); running_sum ( 4 );
sub running_sum { state $sum = 0; state @number; foreach my $number ( @_ ) { push @numbers, $number; $sum += $number; } say "The sum of (@numbers) is $sum"; } 每次我们调用这个子程序的时候,它都会将新的参数与之前的参数相加,因些每次都会输出一个新的总和: The sum of (5 6) is 11 The sum of (5 6 1 2 3) is 17 The sum of (5 6 1 2 3 4) is 21
state @array = qw( a b c ); #错误!
习题: my @fred = qw{1 3 5 7 9}; my $fred_total = total(@fred); print "The total of \@fred is $fred_total.\n"; print "Enter some numbers on separate lines: "; my $user_total = total(<STDIN>); print "The total of those numbers is $user_total.\n";
sub total { my $sum; #私有变量
foreach (@_) { $sum += $_; } $sum; }
|
阅读(690) | 评论(0) | 转发(0) |