10
votes

Puis-je accéder à une méthode statique dans une classe spécifiée dynamiquement dans Perl?

est-il possible de spécifier de manière dynamique une classe en Perl et d'accéder à une méthode statique dans cette classe? Cela ne fonctionne pas, mais illustre ce que j'aimerais faire:

    $class->static_method();  


2 commentaires

Susceptible de m'aider à perdre 15 minutes de l'heure de mon employeur. :)


Je veux dire passer de manière productive.


5 Réponses :


4
votes

Je ne suis pas au courant d'une façon particulièrement agréable de le faire, mais il y a des moyens moins gentils, tels que ce programme: xxx

J'ai inclus un $ classe variable, comme c'était la façon dont vous avez posé la question, et il illustre la manière dont le nom de la classe peut être choisi au moment de l'exécution, mais si vous connaissez la classe à l'avance, vous pouvez aussi facilement appeler & {"Test :: classe1 :: static_method "} (1, 2, 3);

Notez que vous devez éteindre strict" refs " si vous l'avez sur.


2 commentaires

@Im je l'obtiens maintenant. Désolé pour l'édition inutile. J'ai posté une solution à l'aide de chaîne eval pour afficher une autre façon de le faire à l'aide de votre code en tant que modèle.


@Sinan pas un problème! M'a donné une chance d'expliquer plus loin et d'utiliser la fonction "Rollback" pour la première fois. :-)



1
votes

Vous pouvez utiliser string eval : xxx pré> Sortie: P>

             Rate     eval      can nostrict
eval      12775/s       --     -94%     -95%
can      206355/s    1515%       --     -15%
nostrict 241889/s    1793%      17%       --


4 commentaires

Je me demande maintenant quels avantages / inconvénients du pas strict 'REFS' et eval sont des méthodes. Les deux signalent la même erreur si le sous-programme est indéfini. Du point de vue de la vitesse, la méthode non stricte de 'REFS' semble être le gagnant clair (n'a qu'un test simple).


J'aurais aussi tendance à m'éloigner de toute solution impliquée eval "" .


J'ai oublié peut . Vous montre à quel point je fais rarement des choses comme ça.


Merci pour l'effort supplémentaire de comparer les solutions côte à côte. Il semble que puisse ne perd pas grand chose à pas strict 'REFS' dans la performance et est également le moyen le plus clair de le faire.



10
votes

yup! La façon de le faire avec des strictures est d'utiliser peut code> .

    > perl foobar.pl
    yup it can, and it Passed in '' and ran baz!


4 commentaires

+1 peut imo la façon la moins insensée pour le faire. Il encourt toujours toute la chose de héritage qui :: ne le fait pas, mais cela vous permettra de contourner tout le passage à soi / $ CLASS NOME COMME $ _ [0] Comportement.


À tout le moins, si c'est un module, il est probable qu'il n'y ait pas de module "parent". Je n'ai rien vu comme ça, mais un module non de classe qui hérite des méthodes de son parent semble un peu bizarre. Me demande s'il y a un bon usage pour cela ...


@ROBERT P: Il existe définitivement une bonne utilisation pour les fonctions de classe statique dans un module avec un parent. par exemple. J'ai écrit un aujourd'hui pour une famille de manutentionnaires de cache, où les fonctions statiques de l'enfant contenaient des informations de configuration qui devaient augmenter certains comportements dans le parent.


Il vaut probablement la peine de mentionner explicitement que si la fonction statique que vous recherchez n'est pas dans l'emballage que vous utilisez pour appeler peut () alors cette approche suivra tout @isa Définitions Essayer de trouver la fonction statique dans d'autres packages de base à partir duquel celui-ci est dérivé. Cela peut être ou non le comportement que vous êtes après.



2
votes

Il existe trois moyens principaux d'appeler une fonction statique:

  • $ objet-> static_method () code> li>
  • className-> static_method () code> li>
  • Nom de classe :: static_method () code> li> ul>

    Vous pouvez définir votre fonction comme celle-ci: p> xxx pré>

    ou comme ceci, ce qui fonctionne dans les trois scénarios d'appel, et n'aboutit aucun frais de tête sur Le côté de l'appelant comme la solution de Robert P fait: P>

    use UNIVERSAL qw(isa);
    
    sub static_method
    {
        my $class = shift if $_[0] and isa($_[0], __PACKAGE__);
        # ...
    }
    


0 commentaires

5
votes

Comme toujours avec Perl, Il y a plus d'une façon de le faire . < Pré> xxx


0 commentaires