perl:从具有>的模块导出符号1包

时间:2009-11-09 23:52:40

标签: perl

模块foo / bar.pm

package foo::bar;
stuff
stuff
package foo::wizzy;
require Exporter;
our @ISA=qw(Exporter);
our @EXPORT=qw(x);
use constant
{
  x=>1
};

做消费者

use Foo::bar;

未获得foo::wizzy::x导出

我知道我可以把它作为两个单独的模块,但我仍然可以做到这一点,不应该吗?

4 个答案:

答案 0 :(得分:7)

当你致电use foo::bar时,实际发生的事情主要是:

BEGIN {
    require foo::bar;
    foo::bar->import;
}

(见perldoc -f use

因此import永远不会调用foo::wizzy。如果您还要导入这些符号,可以自己致电BEGIN { foo::wizzy->import }use foo::bar之后)。或者,如您所说,只需将这两个包拆分为单独的文件,这将更具人性化。

(顺便说一句,不建议使用较低的包名,因为这些名称通常是为perl pragmata保留的。)

答案 1 :(得分:7)

您可以使用导出程序的export_to_level方法让“主程序包”重新导出“其他”程序包的符号,如下所示:

sub import {
   my $self = shift;
   $self->export_to_level(1, @_);
   Some::Other::Module->export_to_level(1);
}

虽然如果Some::Other::Module做的事情比“导出一切”更复杂,你可能需要对@_进行更精细的处理。

我真的不得不问为什么,但我无法想象这与“好代码”这个词兼容:)

答案 2 :(得分:3)

在模块的最后,输入:

BEGIN { $INC{'foo/wizzy.pm'} = 1 }

然后代码可以说:

use foo::bar;
use foo::wizzy;

获取foo :: wizzy的导出。

答案 3 :(得分:2)

首先,我发现在将多个软件包塞入一个文件时使用封闭大括号来控制范围很有帮助。此外,将包封装在BEGIN块中使其更像是用于加载它的正确use,但这主要是因为我正在将包填充到主脚本中。

use FooBEGIN { require Foo; Foo->import }相同。

所以,你有两个选择:

  • 在主脚本中调用BEGIN{ Foo::Whizzy->import; }
  • 在调用模块上生成Foo::Bar::import触发器Foo::Whizzy::import

在Foo / Bar.pm:

{ package Foo::Bar;
  use Exporter qw( export_to_level );

  # Special custom import.  Not needed if you call Foo::Whizzy->import
  sub import {
    shift;
    export_to_level('Foo::Whizzy', 1, @_ );
  }

  # stuff
  # stuff
}

{ package Foo::Whizzy;
  require Exporter;

  our @ISA=qw(Exporter);
  our @EXPORT=qw(x);
  use constant  { x=>1 };

}

1; # return true

在您的主要代码中:

use Foo::Bar;

# If you don't do a custom import for Foo::Bar, add this line:
BEGIN { Foo::Whizzy->import };