在if块中使用use关键字加载模块时了解perl行为

时间:2014-05-12 16:06:41

标签: perl

到目前为止,我假设use关键字在编译期间加载模块,require在运行时加载模块。如果这是真的,那么在if块中加载模块(使用use)会失败,因为在运行期间块被执行了!

但我尝试使用以下代码测试它。输出告诉我我错了。

#!/usr/bin/perl
my $file = '/home/chidori/dummy.txt';

if ( $file ) {
  use File::Basename;
  my $base_filename = basename($file);
  print "File basename is $base_filename\n";
}

else {
  print "Nothing to display\n";
}

输出

chidori@ubuntu:~$ ./moduletest.pl
File basename is dummy.txt

2 个答案:

答案 0 :(得分:2)

此行为隐含在POD中以供使用。

  

因为"使用"在编译时生效,它并不尊重   正在编译的代码的普通流控制。在   特别是,使用"使用"在一个虚假的分支里面   条件不会阻止它被处理。

use statment是代码解析树的一部分。它在perl的编译阶段执行。 Perl编译不会将use语句添加到解析树。这意味着它不会在程序运行期间执行。

如果您真的很好奇如何解析代码,那么您可以使用B::Deparse检查解析树。

答案 1 :(得分:1)

use Foo;

基本相同
BEGIN {
   require Foo;
   import Foo;
}

它会在编译后立即执行,而不是在程序最终运行时执行。因此,它不受条件和循环的约束。

use File::Basename;置于一个块中是没有意义的,但它对BEGINuse的其他用途有意义。例如,它对词汇编纂有意义。

use warnings;  # Changes compiler settings.
$x;            # Warns.

{
   no warnings;  # Changes compiler settings.
   $x;           # Doesn't warn.

   {
      use warnings;  # Changes compiler settings.
      $x;            # Warns.
   }

   $x;  # Doesn't warn.
}

$x;  # Warns.
1;