3.my变量的其他特性
每次控制抵达my申明,perl创建一个新的,初始的变量。例如,如下代码打印x=1 50次:
for (1 .. 50) { my $x; $x++; print "x=$x\n"; }
每次遍历循环时,你得到一个新的$x,其值初始化为undef。
假如申明在循环之外,控制只会通过它一次,所以这里就只有一个变量:
{ my $x; for (1 .. 50) { $x++; print "x=$x\n"; } }
这会打印x=1, x=2, x=3, ... x=50.
可以利用这点来玩个游戏。假设有个函数,它需要从一个调用到下一个调用中记住某个值。例如,考虑一个随机数产生器。典型的随机数产生器(类似perl的rand函数)有个种子在其中。种子就是一个数。当请求随机数产生器来获取随机数时,该函数基于种子来执行某些运算,然后返回结果。它也会存储该结果,并将其作为下一次函数调用的种子。
如下是典型代码: $seed = 1; sub my_rand { $seed = int(($seed * 1103515245 + 12345) / 65536) % 32768; return $seed; }
输出结果:
16838 14666 10953 11665 7451 26316 27974 27550
这里有个问题,因为$seed是个全局变量,那意味着我们必须担忧某个人可能无意中修改它。或者别人有意破坏它,这就影响了程序的结果。假如该函数用于赌博程序中,并且别人破坏了它的随机数产生器,你想想会发生什么?
但是我们不能在函数里申明$seed为my变量:
sub my_rand { my $seed; $seed = int(($seed * 1103515245 + 12345) / 65536) % 32768; return $seed; }
假如这样做了,当每次调用my_rand时,$seed会被初始化为undef。我们实际需要的是,在每次调用my_rand时,$seed会保留其值。
如下是解决方法:
{ my $seed = 1; sub my_rand { $seed = int(($seed * 1103515245 + 12345) / 65536) % 32768; return $seed; } }
申明在函数之外,所以它仅仅在程序编译时执行一次,而不是每次函数调用时都执行。但它是个my变量,并且其位于代码块里,所以它仅对块里的代码可见。my_rand是块里的唯一其他东西,所以$seed仅可被my_rand函数访问。
4.关于my变量的补充
1)不能对以标点符号命名的变量使用my申明,例如_, @_, 或$$。也不能对后台引用的变量$1, $2, ... 使用my申明。my的作者认为那会把事情搞糟。
2)明显的,不能申明my $DBI::errstr,因为那会有冲突:它认为包变量$DBI::errstr是个词法变量。但是可以申明local $DBI::errstr;它存储local $DBI::errstr的当前值,并在代码块结束处恢复它。
3)在perl 5.004及更高版本里,可以这样写:
foreach my $i (@list) {
它限制$i在循环范围内。类似的,
for (my $i=0; $i<100; $i++) {
限制了$i在for循环里。 |