2009-11-09 12 views
7
moduł

foo/bar.pmPerl: symbole eksportowych z modułu, który ma> 1 opakowanie

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

konsument, który robi

use Foo::bar; 

nie dostać eksporcie foo::wizzy::x

Wiem Mogę zrobić dwa osobne moduły, ale mimo to powinienem móc wykonać tę pracę, czyż nie?

+1

thx wszystkim - konsensus wydaje - wykorzystanie 2 pliki właśnie lenistwo i obiecuję powiedzieć Foo nie foo – pm100

+2

W tym przypadku będę upvote cię! :) – Ether

Odpowiedz

3

Pod koniec modułu, umieścić:

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

Następnie kod może po prostu powiedzieć:

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

uzyskać eksport foo :: wizzy.

+0

ooo - to dobrze - thx – pm100

7

Po wywołaniu use foo::bar, co faktycznie dzieje się to zasadniczo:

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

(patrz perldoc -f use)

Więc import nigdy nie wychodzi wezwał foo::wizzy. Jeśli chcesz importować te symbole, możesz zadzwonić pod numer BEGIN { foo::wizzy->import } (po use foo::bar). Lub, jak powiedziałeś, po prostu podzielisz te dwa pakiety na osobne pliki, które byłyby znacznie bardziej czytelne dla człowieka.

(Nawiasem mówiąc, nie jest wskazane, aby korzystać z niższego obudowane nazwy pakietów, jak te, które są na ogół zarezerwowane dla perl Pragmata.)

+1

OP może również napisać niestandardową metodę 'import' dla foo :: bar, która eksportuje rzeczy z Foo :: wizzy. (Nie, że zrobiłbym to w ten sposób.) –

+4

@Michael: tak, pakuję tylko paczki z kodem na serwetkę, więc w tym momencie pójdę "f ... to, jestem nie oszczędzając czasu od posiadania tych dwóch paczek w jednym pliku "i dzieląc je. – Ether

+0

+1 specjalnie dla powyższego komentarza. –

7

Można to zrobić za pomocą export_to_level metodę eksportera na mieć „pakiet główny” re -export symbole „inny” pakiet jest tak:

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

choć jeśli Some::Other::Module robi coś bardziej skomplikowanego niż „eksportować wszystko” będzie prawdopodobnie trzeba hodowcy obsługę dla @_.

naprawdę muszę zapytać dlaczego, choć — Nie mogę wyobrazić sobie zastosowanie dla tego, co jest zgodne ze słowami „dobry kod” :)

+0

+1 Zapomniałem o "poziomie eksportu" i prawie odtworzono funkcjonalność ;-) –

+1

Tak, zawsze zaczynam być trochę defensywny, gdy widzę, jak ktoś inny miesza się z moim tablicą symboli. To jest jak inwazja osobistej przestrzeni: ty lepiej być w nagłym wypadku lub ożenić się ze mną :) – Ether

2

Po pierwsze, uważam, że warto korzystać z załączając szelki kontrolować zasięg przy pakowaniu wielu pakietów do jednego pliku. Dołączenie paczki do bloku BEGIN powoduje, że działa ona bardziej jak właściwy plik, który został użyty do załadowania go, ale jest to głównie wtedy, gdy pakuję pakiet do głównego skryptu.

use Foo jest taki sam jak BEGIN { require Foo; Foo->import }.

Tak, masz dwie możliwości:

  • połączeń BEGIN{ Foo::Whizzy->import; } w głównym skrypcie.
  • wywołanie Foo::Bar::import wyzwalacza Foo::Whizzy::import na module wywołującym.

W 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 

w głównym kodzie:

use Foo::Bar; 

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