专注各种脚本编程
Baidu
加入收藏夹
本站内容有下面分类知识,欢迎您的到来^_^
shell相关:指令篇 基础篇 脚本欣赏 编程实例 shell问问 shell视频教程 技巧篇 水平测试 E文资料 vi编辑器 高级Bash脚本编程指南
其他:mysql perl c语言 oracle
当前位置:| 主页>perl>

perl变量作用域-词法变量(下篇)

百度收藏 QQ搜藏

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循环里。

上一篇:perl变量作用域-词法变量(中篇) 下一篇:perl变量作用域-变量申明

power by soyo123 2007-2008