先是最常见的解释:
Use
1 use用于载入module
2 use在编译时验证module
Require
1 require用于载入module或perl程序(.pm后缀可以省略,但.pl必须有)
2 require在运行时验证module
其它区别:
use引入模块的同时,也引入了模块的子模块。而require则不能引入
use还调用了import静态函数,告诉包哪些特征将要被导入当前包中
(有一种说法是,use等价于BEGIN{require;import})
例如
use CCC;
require CCC;
require "CCC.pm";
-------------------------------------------------- -----------------------
接下来是动态加载的方法,根据运行时不同状态(变量值)选择载入module,对应的有三种写法:
eval "use $pm_name";
eval "require $pm_name";
#import $pm_name;
require $pm_name.".pm";
可以看到前两种需要借助eval,而require file则是本身支持运行时载入文件。
还有一点我不太明白,eval和编译的顺序是怎样的……
注释掉的import则是关于importpackageexporter的另一个话题了
另外据测试,以上三种方式可以在程序的任何块中运行,包括子函数中。
而在程序运行时,一般来说一个模块是不会被多次载入的。即如下代码是没错的:
sub fun { require $pm; }
for(1..100){ &fun; }
然后测试了下鸡和蛋的问题:
CCC.pm : require DDD;
DDD.pm : require CCC;
main.pl : use/require CCC;
运行的顺序是:
main_start CCC_start DDD_start DDD_end CCC_end main_end
同时DDD调用CCC中的函数也是没问题的。
但是以上,如果CCC和DDD是互相use,会编译错。想一想可以理解,当然编译错……
plus,之所以叫CCC和DDD,不是因为这个问题很CaoDan,而是AAA和BBB被前一个测试用了 - -
-------------------------------------------------- -----------------------
这就差不多了,但是接着又做了一点令人斯巴达克斯的测法。
起因是我手一抖,然后把CCC.pm当做程序入口了。
那么程序是这样的:
主入口:CCC.pm
===>加载DDD.pm
====>加载CCC.pm
但是到此为止了,因为DDD已经被加载过一次了。可是CCC.pm文件确实执行了两次。
还没完,但先把问题简化一下,在上例中去掉DDD,相当于在CCC.pm中require了CCC.pm
虽然这种写法明显的操蛋了,但我还是想记录一下结论:
这个时候,被加载的pm中的变量,相当于在内存空间中有了一个新的拷贝;和入口程序中对应的变量是独立的。
可是被加载的pm中的函数,覆盖了入口程序的函数。
所以你以为在入口程序中调用自己的函数,实际上调用的是被载入pm中的函数,函数内的操作,都是对pm中的变量。
以上基本是猜测,等我有兴趣的时候和黑豹书相关章节参照一下……
附一小段代码和结果:
>>>>>>>>>>>>>>>CCC.pm>>>>>>>>>>>>>>>>>>
require CCC;
my $cnt;
$cnt = 1000;
say "cnt--start: t $cnt";
&say_p();
say "cnt--end: t $cnt";
sub say_p{
$cnt += 1.5;
say "In say_p function:t $cnt";
}
输出结果:
cnt--start: 1000 #pm
In say_p function: 1001.5 #pm
cnt--end: 1001.5 #pm
cnt--start: 1000 #入口
In say_p function: 1003 #pm
cnt--end: 1000 #入口
Use和Require,Perl的引用之路(动态加载)
最新推荐文章于 2023-08-14 10:00:25 发布