免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
123
最近访问板块 发新帖
楼主: neil_young
打印 上一主题 下一主题

web应用mod_perl中的变量申明问题 [复制链接]

论坛徽章:
0
21 [报告]
发表于 2005-11-23 00:47 |只看该作者

大概是这样一个意思

  1. #!/Usr/bin/perl
  2. use strict;

  3. &handle();
  4. &handle();

  5. sub handle{
  6.     my $string = "abcdefg";
  7.     sub inner_sub{
  8.         $string = "1234567";
  9.         print "in inner_sub", $string, "n";
  10.     }
  11.     print "before value", $string, "n";
  12.     print "before ref", $string, "n";
  13.     &inner_sub();
  14.     print "after value", $string, "n";
  15.     print "after ref", $string, "n";
  16. }
复制代码


在上面的代码中,inner_sub是相当于在CGI中定义的函数,$string是相当于CGI中的全局变量,handle是相当于mod_perl编译后加上去的,两次调用相当于是两次请求。

  1. C:web>perl mod_perl_test.pl
  2. before valueabcdefg
  3. before refSCALAR(0x1625c38)
  4. in inner_subSCALAR(0x1625c38)
  5. after value1234567
  6. after refSCALAR(0x1625c38)
  7. before valueabcdefg
  8. before refSCALAR(0x1624ff0)
  9. in inner_subSCALAR(0x1625c38)
  10. after valueabcdefg
  11. 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。

关键就在于里面的是一个命名函数。如果改成非命名函数,就象这样

  1. #!/Usr/bin/perl
  2. use strict;

  3. &handle();
  4. &handle();

  5. sub handle{
  6.     my $string = "abcdefg";
  7.     my $r = sub {
  8.         $string = "1234567";
  9.         print "in inner_sub", $string, "n";
  10.     };
  11.     print "before value", $string, "n";
  12.     print "before ref", $string, "n";
  13.     &$r();
  14.     print "after value", $string, "n";
  15.     print "after ref", $string, "n";
  16. }
复制代码


那样现在里面是一个非命名函数,这样每次执行到sub的时候都要重新编译一次,每次用的$string都是最新一次调用handle产生的$string,所以结果就是每次的前中后都是一样的。

论坛徽章:
0
22 [报告]
发表于 2005-11-23 10:38 |只看该作者
实在是万分感谢 兰花仙子(应该是姐姐吧?)   
还有orangetouch 大侠,讲解得实在是非常仔细清楚!!
感动中

令小生恍然大悟,茅塞顿开!!
不过就是orangetouch 大侠程序中的反斜杠都没有显示啊,大家觉得论坛应该改进一下吗

[ 本帖最后由 neil_young 于 2005-11-23 11:08 编辑 ]

论坛徽章:
0
23 [报告]
发表于 2005-12-11 21:16 |只看该作者
这个帖子偶设为"保留"吧,任何刚接触mod_perl的开发者,都会碰到这个problem的。

另外,如orangetouch所说的,匿名函数并不会导致closure问题,偶想这是因为匿名函数不能构成包的符号的缘故,它export不出去,也就无法通过符号来访问它,故每次都要重新compile了。

[ 本帖最后由 兰花仙子 于 2005-12-11 21:22 编辑 ]
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP