- 论坛徽章:
- 0
|
大概是这样一个意思
- #!/Usr/bin/perl
- use strict;
- &handle();
- &handle();
- sub handle{
- my $string = "abcdefg";
- sub inner_sub{
- $string = "1234567";
- print "in inner_sub", $string, "n";
- }
- print "before value", $string, "n";
- print "before ref", $string, "n";
- &inner_sub();
- print "after value", $string, "n";
- print "after ref", $string, "n";
- }
复制代码
在上面的代码中,inner_sub是相当于在CGI中定义的函数,$string是相当于CGI中的全局变量,handle是相当于mod_perl编译后加上去的,两次调用相当于是两次请求。
- C:web>perl mod_perl_test.pl
- before valueabcdefg
- before refSCALAR(0x1625c38)
- in inner_subSCALAR(0x1625c38)
- after value1234567
- after refSCALAR(0x1625c38)
- before valueabcdefg
- before refSCALAR(0x1624ff0)
- in inner_subSCALAR(0x1625c38)
- after valueabcdefg
- after refSCALAR(0x1624ff0)
复制代码
从上面的结果可以看出来,第二次执行inner_sub时的里面的$string的引用与第一次是一样的,而和第二次调用这个函数前后$string的引用不同。分析一下执行的过程大概是这样的。perl首先会编译这个程序,但是inner_sub这个函数却是在执行到sub inner_sub的时候才编译的。第一次执行到inner_sub的时候,$string已经有了,这时候编译的话,perl就会直接拿现成的$string来用。所以第一次调用的时候$string的前中后的引用值是相同的。但是当第二次执行到sub inner_sub的时候,由于inner_sub是一命名函数。对于命名函数perl只编译一次,所以perl就直接拿上次编译好的inner_sub来用了。但是上次编译好的inner_sub里面的$string指向的是第一次执行handle时产生的$string。所以即使是第二次执行handle,他里面的inner_sub里面的$string指向的也依然是以前的$string。
关键就在于里面的是一个命名函数。如果改成非命名函数,就象这样
- #!/Usr/bin/perl
- use strict;
- &handle();
- &handle();
- sub handle{
- my $string = "abcdefg";
- my $r = sub {
- $string = "1234567";
- print "in inner_sub", $string, "n";
- };
- print "before value", $string, "n";
- print "before ref", $string, "n";
- &$r();
- print "after value", $string, "n";
- print "after ref", $string, "n";
- }
复制代码
那样现在里面是一个非命名函数,这样每次执行到sub的时候都要重新编译一次,每次用的$string都是最新一次调用handle产生的$string,所以结果就是每次的前中后都是一样的。 |
|