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

pm1*_*100 7 perl

module 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
};
Run Code Online (Sandbox Code Playgroud)

这样做的消费者

use Foo::bar;
Run Code Online (Sandbox Code Playgroud)

没有得到foo::wizzy::x出口

我知道我可以把它分成两个独立的模块,但我仍然可以做到这一点,不是吗?

Eth*_*her 7

当你打电话时use foo::bar,实际发生的事情基本上是:

BEGIN {
    require foo::bar;
    foo::bar->import;
}
Run Code Online (Sandbox Code Playgroud)

(参见perldoc -f使用)

因此import永远不会被召唤foo::wizzy.如果你想导入这些符号,你可以打电话给BEGIN { foo::wizzy->import }自己(之后use foo::bar).或者,正如您所说,只需将这两个包拆分为单独的文件,这将更具人性化.

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

  • @Michael:是的,我只把包裹放在一起作为餐巾纸的代码,所以到这时我就去"f--它,我不会节省任何时间将这两个包放在一个文件中"分开他们. (4认同)

hob*_*bbs 7

你可以使用Exporter的export_to_level方法让"主包"重新导出"其他"包的符号,如下所示:

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

虽然如果Some::Other::Module做的事情比"出口一切"更复杂,你可能需要更高级的处理@_.

我真的不得不问为什么,虽然 - 我无法想象这与"好代码"这个词兼容的用法:)


yst*_*sth 3

在模块末尾,输入:

BEGIN { $INC{'foo/wizzy.pm'} = 1 }
Run Code Online (Sandbox Code Playgroud)

那么代码就可以说:

use foo::bar;
use foo::wizzy;
Run Code Online (Sandbox Code Playgroud)

获取 foo::wizzy 的导出。