Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1395000
  • 博文数量: 343
  • 博客积分: 13098
  • 博客等级: 上将
  • 技术积分: 2862
  • 用 户 组: 普通用户
  • 注册时间: 2005-07-06 00:35
文章存档

2012年(131)

2011年(31)

2010年(53)

2009年(23)

2008年(62)

2007年(2)

2006年(36)

2005年(5)

分类:

2010-08-11 10:02:23

首先是最常见的解释:

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则是关于import\package\exporter的另一个话题了

另外据测试,以上三种方式可以在程序的任何块中运行,包括子函数中。
而在程序运行时,一般来说一个模块是不会被多次载入的。即如下代码是没错的:
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 #入口


-----------------------------------------------------

关于不重复载入module,看了一下官方解释:
Perl其实有两个明文变量: @INC和%INC
前者表示搜索modules/lib的路径,后者则是包含所有已加载的module的Hash。
我们知道,可以直接unshift @INC来取代use lib的,那么能不能改变%INC呢,嘿嘿……
%INC中使用模块名作key,完整路径的文件名做value。
所以再加上perl会在所有HOME中所有目录下依次搜索的特性,多次载入同一个pm是可能的……

do
除了use和require,还有一种不常用的引用方式 do
do的用法和require类似,区别是do不会检查%INC中是否已经存在(危险吧,嘿)
对do的详细解释,对use和require的详细解释,参照最后的链接。

library和module
这个太扯了,参照最后的链接。(据验证,链接在墙内。俺是良民。)

阅读(2327) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~