Dans une autre question de Stack Overflow, Leon Timmermans a affirmé:
Je vous conseillerais de ne pas utiliser de prototypes. Ils ont leurs utilisations, mais pas dans la plupart des cas et certainement pas dans celui-ci.
Pourquoi cela pourrait-il être vrai (ou non)? Je fournis presque toujours des prototypes pour mes fonctions Perl, et je n'ai jamais vu personne d'autre dire quelque chose de mal sur leur utilisation.
Réponses:
Les prototypes ne sont pas mauvais s'ils sont utilisés correctement. Le problème est que les prototypes de Perl ne fonctionnent pas comme les gens l'attendent souvent. Les personnes ayant une expérience dans d'autres langages de programmation ont tendance à s'attendre à ce que les prototypes fournissent un mécanisme pour vérifier que les appels de fonction sont corrects, c'est-à-dire qu'ils ont le bon nombre et le bon type d'arguments. Les prototypes de Perl ne sont pas bien adaptés à cette tâche. C'est le mauvais usage qui est mauvais. Les prototypes de Perl ont un but singulier et très différent:
Les prototypes vous permettent de définir des fonctions qui se comportent comme des fonctions intégrées.
Par exemple, vous pouvez définir une fonction comme celle-ci:
et appelez-le comme
sans avoir besoin d'écrire le
\
pour prendre une référence au tableau.En un mot, les prototypes vous permettent de créer votre propre sucre syntaxique. Par exemple, le framework Moose les utilise pour émuler une syntaxe OO plus typique.
C'est très utile mais les prototypes sont très limités:
Voir Prototypes dans perlsub pour tous les détails sanglants.
la source
Le problème est que les prototypes de fonction de Perl ne font pas ce que les gens pensent faire. Leur but est de vous permettre d'écrire des fonctions qui seront analysées comme les fonctions intégrées de Perl.
Tout d'abord, les appels de méthode ignorent complètement les prototypes. Si vous faites de la programmation OO, peu importe le prototype de vos méthodes. (Ils ne devraient donc pas avoir de prototype.)
Deuxièmement, les prototypes ne sont pas strictement appliqués. Si vous appelez un sous-programme avec
&function(...)
, le prototype est ignoré. Donc, ils n'offrent pas vraiment de sécurité de type.Troisièmement, ils sont une action effrayante à distance. (Surtout le
$
prototype, qui provoque l'évaluation du paramètre correspondant dans un contexte scalaire, au lieu du contexte de liste par défaut.)En particulier, ils rendent difficile la transmission de paramètres à partir de tableaux. Par exemple:
imprime:
avec 3 avertissements sur
main::foo() called too early to check prototype
(si les avertissements sont activés). Le problème est qu'un tableau (ou une tranche de tableau) évalué dans un contexte scalaire renvoie la longueur du tableau.Si vous avez besoin d'écrire une fonction qui agit comme une fonction intégrée, utilisez un prototype. Sinon, n'utilisez pas de prototypes.
Remarque: Perl 6 aura des prototypes complètement repensés et très utiles. Cette réponse s'applique uniquement à Perl 5.
la source
foo()
impressions 2 car c'est le dernier élément de votre tranche à deux éléments. Changez pourmy @array = qw(foo bar baz)
et vous verrez la différence. (En passant, c'est pourquoi je n'initialise pas les tableaux / listes à des séquences numériques basées sur 0 ou 1 dans un code démonstratif jetable. La confusion entre les indices, les décomptes et les éléments dans les contextes m'a mordu plus d'une fois. Silly mais vrai.)a b c
pour clarifier votre point de vue.Je suis d'accord avec les deux affiches ci-dessus. En général, l'utilisation
$
doit être évitée. Prototypes ne sont utiles que lors de l' utilisation de blocs (arguments&
), (globules*
) ou prototypes de référence (\@
,\$
,\%
,\*
)la source
($)
prototype crée un opérateur unaire nommé, qui peut être utile (certainement Perl les trouve utiles; moi aussi, à l'occasion). Deuxièmement, lorsque vous remplacez les composants intégrés (que ce soit via l'importation ou en utilisant CORE :: GLOBAL: :), vous devez en général vous en tenir à n'importe quel prototype intégré, même si cela inclut un$
, ou vous pourriez surprendre le programmeur (vous-même, even) avec un contexte de liste où le intégré fournirait autrement un contexte scalaire.Certaines personnes, en regardant un prototype de sous-programme Perl, pensent que cela signifie quelque chose que ce n'est pas:
Pour Perl, cela signifie que l'analyseur attend deux arguments. C'est la façon dont Perl vous permet de créer des sous-programmes qui se comportent comme des composants intégrés, qui savent tous à quoi s'attendre du code suivant. Vous pouvez en savoir plus sur les prototypes dans perlsub
Sans lire la documentation, les gens supposent que les prototypes font référence à la vérification des arguments d'exécution ou à quelque chose de similaire qu'ils ont vu dans d'autres langues. Comme pour la plupart des choses que les gens pensent à propos de Perl, elles se révèlent fausses.
Cependant, à partir de Perl v5.20, Perl a une fonctionnalité, expérimentale au moment où j'écris ceci, qui donne quelque chose de plus comme ce que les utilisateurs attendent et quoi. Les signatures de sous - programmes de Perl exécutent le comptage des arguments, l'attribution des variables et les paramètres par défaut:
C'est la fonctionnalité que vous souhaitez probablement si vous envisagez des prototypes.
la source