2009-11-09 45 views
7

模塊富/ 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

回答

3

在模塊的末尾,放:

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

然後代碼就可以說:

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

獲得foo :: wizzy的出口。

+0

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

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

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

7

可以使用出口商的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

2

首先,我發現它有助於用花括號兼容在將多個包壓縮到一個文件時控制範圍。另外,將軟件包封裝在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 };