的Perl:从模块输出符号具有> 1包

问题描述:

模块富/ bar.pm的Perl:从模块输出符号具有> 1包

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出口

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

+1

THX所有 - 的共识似乎 - 使用2个文件 我只是懒惰 我保证说美孚不是foo – pm100 2009-11-10 00:21:48

+2

在这种情况下,我会给予好评你! :) – Ether 2009-11-10 00:28:37

在模块的末尾,放:

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

然后代码就可以说:

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

获得foo :: wizzy的出口。

+0

噢 - 这是一个很好的 - thx – pm100 2009-11-10 19:48:59

当你调用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

OP也可以为foo :: bar编写一个自定义'import'方法,用于从Foo :: wizzy中导出内容。 (不是说我会那样做。) – 2009-11-10 00:12:06

+4

@Michael:是的,我只是把软件包放在一起作为餐巾后面的代码,所以在这一点上我会去“f--它,我是不会将这两个软件包保存在一个文件中“并将它们分开。 – Ether 2009-11-10 00:19:02

+0

+1对于上面的评论尤其如此。 – 2009-11-10 00:21:07

可以使用出口商的export_to_level方法有“主包”做重-export“其他”包装的符号,像这样:

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

但如果Some::Other::Module做一些事情比更复杂的“出口一切”,你可能会需要票友处理的@_

我真的要问为什么,虽然—我无法想象这是一个使用这的话“好码” :)

+0

+1我忘记了'export_to_level'并且几乎重新创建了功能;-) – 2009-11-10 00:19:29

+1

是的,当我看到有人在乱动我的符号表时,我总是开始有点防御......这就像侵入个人空间:你最好是在紧急情况下,或与我结婚:) – Ether 2009-11-10 00:29:39

首先,我发现它有助于用花括号兼容在将多个包压缩到一个文件时控制范围。另外,将软件包封装在BEGIN块中使其更适合于使用use来加载它,但这主要是如果我将软件包压缩到主脚本中。

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

所以,你有两个选择:

  • 通话BEGIN{ Foo::Whizzy->import; }在主脚本。
  • 使Foo::Bar::import在调用模块上触发Foo::Whizzy::import

In 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 };