Une caractéristique Perl peu connue est les attributs. Cependant, le fonctionnaire documentation fait un travail plutôt mauvais présentant des débutants au concept. Dans le même temps, les frameworks comme Catalyst utilisent beaucoup d'attributs ce qui semble faciliter beaucoup de choses là-bas. Comme j'utilise quelque chose sans en connaître les implications, je voudrais connaître les détails. Syntaxe-sage ils ressemblent aux décorateurs de Python, mais la documentation implique quelque chose de plus simple. Pourriez-vous expliquer (avec des exemples concrets si possible) quels attributs sont bons et ce qui se passe derrière les portes?Comment les attributs de la méthode Perl fonctionnent-ils?
Répondre
Vous avez raison, la documentation n'est pas très claire dans ce domaine, d'autant plus que les attributs ne sont pas si compliqués.Si vous définissez un attribut de sous-programme, comme ceci:
sub some_method :Foo { }
Perl lors de la compilation de votre programme (ce qui est important) chercher la sous MODIFY_CODE_ATTRIBUTES
magique dans le package actuel ou l'une de ses classes parentes. Ceci sera appelé avec le nom du paquet courant, une référence à votre sous-programme, et une liste des attributs définis pour ce sous-programme. Si ce gestionnaire n'existe pas, la compilation échouera.
Ce que vous faites dans ce gestionnaire dépend entièrement de vous. Oui c'est vrai. Aucune magie cachée. Si vous souhaitez signaler une erreur, renvoyer le nom des attributs incriminés entraînera l'échec de la compilation avec un message "attribut invalide".
Il y a un autre gestionnaire appelé FETCH_CODE_ATTRIBUTES
qui sera appelée à chaque fois que quelqu'un dit
use attributes;
my @attrs = attributes::get(\&some_method);
Ce gestionnaire est transmis le nom du package et de référence sous-programme, et est censé retourner une liste des attributs du sous-programme (bien que ce que vous vraiment faire est de nouveau à vous).
Voici un exemple pour permettre simple « marquage » des méthodes avec des attributs arbitraires, que vous pouvez interroger plus tard:
package MyClass;
use Scalar::Util qw(refaddr);
my %attrs; # package variable to store attribute lists by coderef address
sub MODIFY_CODE_ATTRIBUTES {
my ($package, $subref, @attrs) = @_;
$attrs{ refaddr $subref } = \@attrs;
return;
}
sub FETCH_CODE_ATTRIBUTES {
my ($package, $subref) = @_;
my $attrs = $attrs{ refaddr $subref };
return @$attrs;
}
1;
Maintenant, dans MyClass et toutes ses sous-classes, vous pouvez utiliser des attributs arbitraires et requête les utiliser attributes::get()
:
package SomeClass;
use base 'MyClass';
use attributes;
# set attributes
sub hello :Foo :Bar { }
# query attributes
print "hello() in SomeClass has attributes: ",
join ', ', attributes::get(SomeClass->can('hello'));
1;
__END__
hello() in SomeClass has attributes: Foo, Bar
en résumé, les attributs ne font pas beaucoup d'importance, d'autre part les rend très flexible: Vous pouvez les utiliser comme vrai « attributs » (comme indiqué dans cet exemple), mettre en œuvre quelque chose comme les décorateurs (voir Sinan's answer), ou pour vos propres fins sournoises.
Les attributs sont l'une des choses que si vous ne savez pas comment les utiliser, vous ne devriez pas les déranger avec eux. Une fois, j'ai fait un attribut database_method
, pour indiquer au système qu'un ensemble d'enregistrements serait demandé avant d'entrer dans cette méthode et que la méthode savait que ses entrées principales proviendraient de la procédure stockée à laquelle elle correspondait. J'utilisais des attributs pour envelopper les actions spécifiques spécifiées avec ces données. Donc, l'une des idées vraiment utiles est d'envelopper les méthodes avec indirection, mais il était plus difficile de faire fonctionner l'appelant, sans l'ignorer. En fin de compte, il était beaucoup trop visible comme une fonctionnalité «expert seulement» et aurait besoin de soutien pour tracer à travers les entrailles arcanes - quelque chose que vous voulez éviter, si vous écrivez Perl dans un magasin perl-aussi.
Les gens peuvent vouloir voter contre moi, mais je prends de l'article cité par Sinan:
Avertissements
Bien que ce soit une technique puissante, il est pas parfait . Le code n'emballe pas correctement les sous-programmes anonymes, et il ne propagera pas nécessairement le contexte d'appel aux fonctions enveloppées. En outre, l'utilisation de cette technique augmentera considérablement le nombre de distributions de sous-programmes que votre programme doit exécuter pendant l'exécution. En fonction de la complexité de votre programme, cela peut augmenter considérablement la taille de votre pile d'appels. Si la vitesse aveuglante est un objectif de conception majeur, cette stratégie peut ne pas être pour vous.
Ce sont importants inconvénients à moins que vous êtes prêt à passer outre caller
. Je ne me soucie pas autant de la "vitesse aveuglante", et je suis à moitié prêt à essayer de contourner n'importe quel sous-programme qui s'enregistre comme "DO_NOT_REPORT" - mais j'ai un peu de folie qui n'a pas de codage. Je n'ai pas encore été battu hors de moi aussi.
Même l'article admet à quel point cette fonctionnalité est mal documentée, et contient cette mise en garde. Dites-moi quand d'autre a été une bonne idée d'utiliser une fonctionnalité snazzy, obscure? Cela suffit souvent, les gens finissent par mettre dans l'espace de noms UNIVERSAL
pour éviter le problème d'héritage.
(Mais si vous pensez qu'il est une mauvaise réponse, juste une autre downvote me donnera un badge de pression par les pairs: D)
Vrai, mais ces avertissements s'appliquent uniquement à cette façon particulière d'utiliser les attributs, qui est d'envelopper la méthode d'origine. Dans la plupart des cas où les attributs sont utilisés (Catalyst, etc.), ils sont simplement utilisés pour le marquage (je pense), ce qui n'est pas du tout problématique. – trendels
Encore que ce soit donné comme l'une des principales utilisations dans l'un des tutoriels Perl les plus clairs (celui qui m'aurait permis de gagner du temps) sur le sujet. Je dois admettre que je n'ai pas encore vérifié à Catalyst. – Axeman
$perl->buzz recommande Mike Friedman's article.
@brian Merci pour la correction. Je vais blâmer la perception sélective pour choisir seulement votre nom sur la liste des auteurs sur cette page ;-) Maintenant que je regarde à nouveau, il est évident que Mike Friedman est l'auteur. –
- 1. Convertir les attributs de style CSS en attributs HTML en utilisant Perl
- 2. Les attributs de méthode sont-ils hérités en C#?
- 3. Analyse des éléments et des attributs XML avec Perl
- 4. Expression simple perl pour supprimer les esperluettes échappées de l'intérieur des attributs href mais pas ailleurs
- 5. Comment supprimer les attributs de formulaire dans Zend Framework?
- 6. Comment installer les dépendances de script Perl?
- 7. Comment puis-je récupérer les attributs d'images?
- 8. Attributs personnalisés sur les membres de la classe
- 9. A get() comme méthode de vérification des attributs Python
- 10. Quels sont les attributs?
- 11. XPath: Comment sélectionner les nœuds sans attributs?
- 12. Comment inspecter ou rechercher les attributs .NET?
- 13. Pourquoi l'appel SUPER de Perl n'utilise-t-il pas la méthode de la flèche?
- 14. DirectoryInfo.GetDirectories() et les attributs
- 15. Définir les attributs pour les paramètres de demande SOAP PHP
- 16. Puis-je conditionnellement contrôler les appels de méthode à l'exécution avec des attributs?
- 17. .net - Comment utiliser les attributs et y compris les arguments?
- 18. Modifier les attributs de la classe CSS avec javascript?
- 19. Comment agréger tous les attributs d'une hiérarchie de classes?
- 20. Exploiter la puissance des attributs .NET
- 21. Comment modifier les attributs de sécurité d'annuaire à l'aide d'InstallShield?
- 22. TouchXML analyse les attributs XML
- 23. Récupère les attributs personnalisés d'un membre spécifique
- 24. Comment factoriser les entiers en utilisant Perl?
- 25. Comment déchiffrer les documents de la méthode Select sur MSDN?
- 26. Comment obtenir les paramètres de la méthode get dans jsp?
- 27. DBML supprime les attributs .Name?
- 28. Lire les valeurs des attributs avec linq
- 29. Comment remplacer le code de la chaudière par des attributs?
- 30. Comment copier des liens symboliques en Perl?
Excellente réponse !!! :RÉ – gideon