2010-02-17 15 views
2

Aidez Perlers! Est-ce que quelqu'un sait qu'une simple approche "insérer le code ici" apporterait le code des fichiers externes une fois à la compilation dans un paquet?Comment puis-je importer du code Perl à partir de fichiers externes au moment de la compilation?

Contexte:

J'ai un style PBP classe standard inside-out qui devient assez grand. Je veux diviser le code en plusieurs fichiers mais pas étendre la classe. Idéalement, je voudrais simplement insérer le code dans la section "Magic JuJu" du module d'exemple (voir ci-dessous) une fois au moment de la compilation.

J'ai regardé AutoLoader comme un moyen d'accomplir ceci. Cependant, il y a deux choses qui me font réfléchir. Si je pouvais contourner ces, il pourrait être une solution quasi-optimale:

  1. Je ne veux pas diviser tous les petits sous dans un fichier séparé; juste un peu plus de fichiers de taille raisonnable (en utilisant des sous-talons dans l'appelant est très bien, cependant); et

  2. Je ne veux pas différer la compilation sur tous les sub; certains sous-marins que je voudrais avoir compilé lors de l'utilisation initiale. Cependant, ce n'est probablement pas un briseur d'affaire.

Je sais Moose fournit des « rôles » que je crois le fait bien, mais pour diverses raisons, Moose est pas une option pour ce projet, ni souris. J'ai utilisé "require q (some/file)" dans l'emplacement "Magic JuJu", mais cela ne maintient pas la portée de la variable persistante, ie les sous-fichiers du fichier externe ne "voient" pas les hachages de l'attribut object correctement (autrement dit, mettre le require en haut du fichier aurait le même effet). Je pourrais contourner cela en utilisant toujours des setters et des getters. Donc, ce n'est pas une rupture d'accord, mais cela nécessiterait un peu de temps de codage et des frais généraux d'exécution que je préférerais ne pas encourir.

Enfin, je ne veux pas étendre la classe; il a déjà plusieurs héritages. Je veux juste un simple "insérer le code ici" approche apporterait le code une fois à la compilation.

En résumé:

  1. Code importations (Obligatoire) à partir de fichiers externes dans l'espace de noms de package
  2. (obligatoire) ne le fait que lors de la compilation ou les frais généraux d'exécution minimale
  3. (obligatoire) Est-ce que pas étendre la classe
  4. (souhaité) insérer l'emplacement Honneurs champ

Exemple de code avec un commentaire "magic JuJu" ci-dessous:

package T; 

use strict; 
use warnings; 

########## BEGIN object persistent variables scope block ############ 
{ 
    my %Attr_Name_Env; 

    ## Constructor 'new' 
    # 
    sub new { 
    ## Get and confirm arguments 
    # 
    my $class  = shift; 
    my $href_arg = {@_}; 
    my $name_env = $href_arg->{'name_env'}; 

    ## Bless anon scalar into class 
    # 
    my $obj_new = bless anon_scalar(), $class; 
    my $idx_self = ident $obj_new; 

    # Populate object attributes 
    # 
    $Attr_Name_Env{ $idx_self } = $name_env; 

    return $obj_new; 
    } 
    ## END Constructor 'new' 

    sub DESTROY {... as you do ...} 

    sub t_get_name_env { 
    my $self  = shift; 
    my $idx_self = ident $self; 
    return $Attr_Name_Env{ $idx_self }; 
    } 

    ## insert magic juju here 

} 
########## END object persistent variables scope block ############ 

1; 

Peut-être un bloc BEGIN avec un slurp et eval ...

+0

Pourquoi vous souciez-vous de la taille de la classe? –

Répondre

2

Vous pouvez simplement utiliser les modules et importer les sous-marins souhaités.

use MyMod qw(wanted_sub_1 wanted_sub2); 

Pour obtenir un accès à votre attribut hash vous devez modifier import pour vos modules cibles.

package MyClass; 
use MyMod { attrib1 => \%attrib1, attrib2 => \%attrib2 }, qw(wanted_sub1 wanted_sub2); 

de importMyMod ensuite créer refs de code qui sont fermés sur l'argument de hachage initial, et les installer dans l'espace de noms MyClass.

+0

1. Les attributs sont étendus lexicalement à travers un bloc conteneur, de sorte qu'ils ne seraient pas disponibles pour MyMod à moins que ce bloc conteneur ne soit supprimé. Cela rendrait les attributs pas vraiment privés, mais cela pourrait être acceptable. Ou on pourrait utiliser uniquement des accesseurs pour les attributs. 2. Les sous-marins MyMods voudront utiliser des méthodes de la classe, en particulier les méthodes héritées. Je pense que cela fonctionnera avec l'approche standard "my $ self = shift", mais devra tester. 3. Un peu verbeux, mais peut-être est le plus correct. Rendra compte. Plus je lis, plus je crains les filtres sources –

+0

Je l'ai fait en utilisant cette méthode! La méthode d'importation est un peu obtuse pour le développeur moyen, et c'est un peu bavard. Mais c'est propre et ça fonctionne, et certainement très perl-ish. De plus, perl -cw fonctionne sur chaque module, ce qui est très agréable. Filter :: Macro n'a pas fonctionné, et semble un peu trop magique pour cette application. –

+1

BTW, pour voir le code de travail réel, rendez-vous ici: http://perlmonks.org/?node_id=823764 –

1

Si vous êtes prêt à vivre avec les conséquences, il y a Filter::Macro.

+1

Non, pas de filtres! L'horreur, l'horreur! –

+0

Salut Sinan! Je vous remercie! Filtre :: Macro ressemble certainement à un bon choix. Vous mentionnez les conséquences, ci-dessus. Pourriez-vous partager avec moi ce que cela pourrait être? –

+0

@Michael: Vous utiliserez un filtre source. ;-) 'Filter :: Macro' est assez simple pour que je ne pense pas que ce soit un problème, mais les filtres source ont tendance à être un peu fragiles et je ne sais pas si' Filter :: Macro' est sûr à utiliser avec tous les autres modules là-bas. –