require
require Math::Calc;
当脚本运行到上面的语句时,将遍历数组@INC中的目录,检查是否有一个名为Math的子目录和Math子目录中是否有一个Calc.pm的文件。当它找到这样一个文件的时候,机器将会将它加载到内存中,编译它并停止搜索。这将会允许你使用这个函数的所有功能,比如Math::Calc::add();
use
如果你又下面代码的任意一行:
use Math::Calc;
use Math::Calc qw(add);
然后perl将在脚本编译时加载并编译模块。那是因为在使用的脚本中将被下面的代码取代:
BEGIN {
require Math::Calc;
Math::Calc->import( qw(add) );
}
BEGIN代码块代表当脚本编译结束立马开始运行BEGIN代码块里面的代码。
所以在编译阶段,当perl完成编译BEGIN代码块的时候,它将停止编译并执行里面的代码。第一个语句require Math::Calc;代表找到Math/Calc.pm文件,加载并编译它。第二个语句Math::Calc->import( qw(add) );代表如果有这个方法,就运行导入这个模块(如果没有要导入的方法就什么都不做)。
如果用户输入的是use Math::Calc…也输入了列表值,就像我们例二中的qw(add)一样,然后这个列表会被传给import方法。
import方法取决于模块(Math::Calc)的作者,但是在大多数情况下它会安排add函数在被申明的时候插入命名空间中,为了码农不需要提供完整的名字Math::Calc::add()只要使用add就可以调用了。
换句话说,import方法将add方法加载到了用户的命名空间中了。
所以这就是差异。require发生在运行时;use发生在编译时,除了加载模块,它还会将导入的一些函数放到当前的命名空间中。
条件性加载
有些人可能只想在某些条件下才加载该模块,所以他们这样写:
if ($holiday) {
use Vacation::Mode;
}
无论把上面的代码放在什么位置,它都不会像我们期待的那样起效果。它还是会在编译的时候执行。当perl编译这个脚本并到if语句的时候,它将加载Vacation::Mode模块并导入它的的函数,根本不管在运行的时候$holiday是否有值。
如果你想在改条件成立的情况下加载该模块,为了节省启动的时间或者省内存,你可以这样编写:
if ($holiday) {
require Vacation::Mode;
Vacation::Mode->import;
}
这是因为require只在运行时执行,所以这段代码只会在运行时被执行,并且只有在$holiday有值的情况下运行。