Perl 变量魔法

先来看一段 Perl 脚本:

sub showVars {

my $name = “first”;
print $name . “\t at ” . \$name . “\n”;
for(my $i = 0; $i < 2; $i++) { my $name = "loop_" . $i; if (1 < 3) { print $name . "\t at " . \$name . "\n"; my $name = "if_A"; print $name . "\t at " . \$name . "\n"; { my $name = "blank"; print $name . "\t at " . \$name . "\n"; } print $name . "\t at " . \$name . "\n"; } if (1 < 4) { print $name . "\t at " . \$name . "\n"; my $name = "if_B"; print $name . "\t at " . \$name . "\n"; } print $name . "\t at " . \$name . "\n"; } print $name . "\t at " . \$name . "\n"; } sub showVars_2 { my $name = "first"; print $name . "\t at " . \$name . "\n"; for(my $i = 0; $i < 2; $i++) { $name = "loop_" . $i; if (1 < 3) { print $name . "\t at " . \$name . "\n"; $name = "if_A"; print $name . "\t at " . \$name . "\n"; { $name = "blank"; print $name . "\t at " . \$name . "\n"; } print $name . "\t at " . \$name . "\n"; } if (1 < 4) { print $name . "\t at " . \$name . "\n"; $name = "if_B"; print $name . "\t at " . \$name . "\n"; } print $name . "\t at " . \$name . "\n"; } print $name . "\t at " . \$name . "\n"; } showVars(); print "--------------\n"; showVars_2();

这里面有 2 个函数,两者之间的区别,就是变量的定义方式不同。

第一个函数,多次使用 my 声明变量。Perl 会在每一个局部区域内,比如说大括号 {} 内,实现一个命名空间。
也就是说,在不同的代码段,相同的变量名,实际上指向了不同的内存地址。
第一个函数体内,首先声明了一个变量 $name,他的作用域是整个函数,但在 for 循环体内,又用 my 声明了 $name 变量,因为 for 是一个封闭的结构,在 {} 里面就可以产生一个新的命名空间,此时 $name 指向了一个新的内存地址。这一点可以在后面的输出结果中看到。

由此,引发一个值得思考的问题:
如果在循环体内部用 my 去声明变量,那么循环执行多少次,就会有多少个变量的副本,这会浪费很多内存空间。
这一点是跟其他类 C 语言是有很大区别的。
所以,如果你要想利用 Perl 的命名空间,那么只要多注意代码段的作用范围,编程的时候能感受到 Perl 十分强大的便利性。
需要注意的,就是避免在循环体中使用 my 声明,浪费内存空间不说,还会影响程序的性能。

说了半天,还是看一看实际的结果吧:

$ perl show_vars.pl
first at SCALAR(0x182fb10)
loop_0 at SCALAR(0x182fbb8)
if_A at SCALAR(0x182fc24)
blank at SCALAR(0x182fc84)
if_A at SCALAR(0x182fc24)
loop_0 at SCALAR(0x182fbb8)
if_B at SCALAR(0x182fd5c)
loop_0 at SCALAR(0x182fbb8)
loop_1 at SCALAR(0x182fd5c)
if_A at SCALAR(0x182fc84)
blank at SCALAR(0x276164)
if_A at SCALAR(0x182fc84)
loop_1 at SCALAR(0x182fd5c)
if_B at SCALAR(0x182fc24)
loop_1 at SCALAR(0x182fd5c)
first at SCALAR(0x182fb10)
————–
first at SCALAR(0x182fe88)
loop_0 at SCALAR(0x182fe88)
if_A at SCALAR(0x182fe88)
blank at SCALAR(0x182fe88)
blank at SCALAR(0x182fe88)
blank at SCALAR(0x182fe88)
if_B at SCALAR(0x182fe88)
if_B at SCALAR(0x182fe88)
loop_1 at SCALAR(0x182fe88)
if_A at SCALAR(0x182fe88)
blank at SCALAR(0x182fe88)
blank at SCALAR(0x182fe88)
blank at SCALAR(0x182fe88)
if_B at SCALAR(0x182fe88)
if_B at SCALAR(0x182fe88)
if_B at SCALAR(0x182fe88)

Leave a Reply

Your email address will not be published.

*