关于Perl中do函数执行规则及非限定名使用的技术问询
关于Perl中
do函数执行包上下文的规则解释 这个问题的核心是理解Perl里do FILE的执行上下文继承机制,咱们一步步拆解:
1. do FILE会完全继承当前的包语境
当你在package bar;代码块里调用do('test.pl')时,test.pl里的所有代码都会在当前的bar包上下文里执行,而不是默认的main包。这就相当于把test.pl里的代码直接复制粘贴到package bar;这个块里运行,效果完全一致。
所以test.pl里的%h_test = ('b' => 'blah');,本质上就是%bar::h_test = ('b' => 'blah');——因为当前包是bar,非限定的包变量会自动绑定到当前包的符号表。
2. 和直接写代码的等价性对比
你原来的函数:
sub foo { package bar; %bar::h_test = ('b' => 'blah'); }
其实如果去掉包限定,写成:
sub foo { package bar; %h_test = ('b' => 'blah'); }
在启用strict和warnings的情况下也能正常运行——因为此时%h_test就是当前包bar的包变量,符合strict 'vars'的规则(strict 'vars'只阻止未声明的词法变量和非当前包的未限定包变量)。
而do('test.pl')只是把外部文件的代码代入到当前语境,和上面这个写法没有区别。
3. 验证小技巧
如果想确认这一点,可以在test.pl里加一行代码:
print "当前执行包: ", __PACKAGE__, "\n";
调用foo()之后,你会看到输出当前执行包: bar,直接证明了test.pl的代码是在bar包下运行的。
额外提醒
如果想让test.pl的代码始终在main包运行,不管调用的语境,只需要在test.pl开头加上package main;声明即可——这样非限定变量就会绑定到main包的符号表了。
内容的提问来源于stack exchange,提问作者Yakov Dan
相关产品推荐
相关产品推荐

