use vs require in Perl5

Perl5 的程序执行分为两个阶段:compilation time & run time。而 use 与 require 依次发生在这两个不同的阶段。
值得注意的是:Parser对use的处理等同如下:

use strict;

like

BEGIN{
    require 'strict.pm';
    strict->import();
}

NOTE:BEGIN block是在compilation time触发执行(赋值)过程。

也就是说,strict 中所定义的variables & subroutines已于compilation time在data structure(optree)中赋值并存在了。
接下来通过对不同路径下,拥有相同包package name or file name的文件导入来分析它们的不同表现。

use PACKAGE;

/tmp/amy_dir/hello.pm

sub say(){
    print "Hello! I am Amy\";
}
1;
__END__;

/tmp/bob_dir/hello.pm

sub say(){
    print "Hello! I am Bob\";
}
1;
__END__;

/tmp/say_hello.pl

use lib "/tmp/amy_dir";
use hello;
hello->say();

use lib "/tmp/bob_dir";
use hello;
hello->say();

运行结果:

[root@VTB93-PC1 tmp]# perl say_hello.pl
Hello! I am Amy
Hello! I am Amy

分析:上面提到 use 等同 BEGIN{…}。amy_dir目录下的 hello.pm 先被赋值于optree中, 后续Parser再遇上 bob_dir下的hello.pm时,发现optree中已存在以此包名为值的 key,将不再进行二次赋值。所以在 run time 顺序执行代码时,所有对 hello->say() 的调用都是参照/tmp/amy_dir/hello.pm

require “some_file.pl(pm)”;

Perl5对 require 的处理是在 run time。当执行require时会在run time触发编译。
接下来将/tmp/say_hello.pl中的 use 部分替换成 require 后:

[root@VTB93-PC1 tmp]# vi say_hello.pl

use lib "/tmp/amy_dir";
require 'hello.pm';
hello->say();

use lib "/tmp/bob_dir";
require 'hello.pm';
hello->say();

运行结果:

[root@VTB93-PC1 tmp]# perl say_hello.pl
Hello! I am Bob
Hello! I am Bob

分析:在run time 执行到 require 语句触发编译。这边可以理解为 say_hello.pl 中最终包含了 /tmp/bob_dir/hello.pm 中的代码。这是由于 @INC 中的优先路径为 /tmp/bob_dir/。导致 @INC 如此的是由于编译时,两次 use lib 操作的顺序所致。

[root@VTB93-PC1 tmp]# perl say_hello.pl
Hello! I am Bob
Dump @INC
(
  "/tmp/bob_dir",
  "/tmp/amy_dir",
  "/usr/local/lib/perl5",
  "/usr/local/share/perl5",
  "/usr/lib/perl5/vendor_perl",
  "/usr/share/perl5/vendor_perl",
  "/usr/lib/perl5",
  "/usr/share/perl5",
  ".",
)
Hello! I am Bob
Dump @INC
(
  "/tmp/bob_dir",
  "/tmp/amy_dir",
  "/usr/local/lib/perl5",
  "/usr/local/share/perl5",
  "/usr/lib/perl5/vendor_perl",
  "/usr/share/perl5/vendor_perl",
  "/usr/lib/perl5",
  "/usr/share/perl5",
  ".",
)

结论:

  1. 先后 use 不同路径下,拥有相同package name的 pm,只会导入第一个pm
  2. 先后 require 不同路径下,拥有相同name的pl or pm file, 只会导入后一个file
  3. use lib LIST, 对@INC进行unshift操作
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值