2009-11-09 3 views
7

Module foo/bar.pmperl: symboles d'exportation de module qui a> 1 paquet

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

un consommateur qui fait

use Foo::bar; 

ne reçoit pas l'exportation foo::wizzy::x

Je sais Je peux en faire deux modules séparés, mais je devrais être capable de faire ce travail, n'est-ce pas?

+1

thx à tous - le consensus semble - utiliser 2 fichiers J'étais juste paresseux et je promets de dire Foo pas foo – pm100

+2

Dans ce cas, je vais vous upvote! :) – Ether

Répondre

3

A la fin du module, mis:

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

code, puis peut simplement dire:

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

pour obtenir les exportations de foo :: wizzy.

+0

ooo - c'est un bon - merci – pm100

7

Lorsque vous appelez use foo::bar, ce qui se passe en réalité est essentiellement:

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

(voir perldoc -f use)

Alors import est jamais s'invoqua foo::wizzy. Si vous souhaitez également importer ces symboles, vous pouvez appeler le BEGIN { foo::wizzy->import } vous-même (après use foo::bar). Ou, comme vous l'avez dit, il suffit de diviser ces deux paquets en fichiers séparés, ce qui serait beaucoup plus lisible par l'homme.

(Soit dit en passant, il est déconseillé d'utiliser des noms de paquets en minuscules, comme ceux-ci sont généralement réservés pour pragmata perl.)

+1

L'OP pourrait aussi écrire une méthode 'import' personnalisée pour foo :: bar qui exporte le contenu de Foo :: wizzy. (Ce n'est pas que je le ferais de cette façon.) –

+4

@Michael: Oui, je ne fais que mettre des paquets ensemble pour le code de retour d'une serviette, donc à ce moment-là, j'irais "f-- ça, je suis ne pas gagner du temps d'avoir ces deux paquets dans un fichier "et les séparer. – Ether

+0

+1 spécialement pour le commentaire ci-dessus. –

7

Vous pouvez le faire en utilisant la méthode export_to_level de l'exportateur pour avoir le « paquet principal » re -EXPORT les symboles de paquet « autres » comme ceci:

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

mais si Some::Other::Module fait quelque chose de plus compliqué que « exporter tout », vous aurez probablement besoin d'une manipulation pour colombophile @_.

Je dois vraiment demander pourquoi, si — je ne peux pas imaginer une utilisation pour ce qui est compatible avec les mots « bon code » :)

+0

+1 J'ai oublié 'export_to_level' et presque recréé la fonctionnalité ;-) –

+1

Oui, je commence toujours à être un peu sur la défensive quand je vois quelqu'un d'autre jouer avec ma table de symboles .. c'est comme une invasion de l'espace personnel: vous mieux être en cas d'urgence, ou marié à moi :) – Ether

2

Tout d'abord, je trouve utile d'utiliser des accolades enfermant pour contrôler la portée lors du bachotage de plusieurs paquets en un seul fichier. De plus, en incluant le paquet dans un bloc BEGIN, cela fonctionne plus comme un bon use a été utilisé pour le charger, mais c'est surtout si je compile le paquet dans le script principal.

use Foo est la même que BEGIN { require Foo; Foo->import }.

Donc, vous avez deux choix:

  • appel BEGIN{ Foo::Whizzy->import; } dans votre script principal.
  • make Foo::Bar::import déclencher le Foo::Whizzy::import sur le module appelant.

Dans Foo/Bar.h:

{ 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 

Dans votre code principal:

use Foo::Bar; 

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