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:
my @array = qw(a b c);
foo(@array);
foo(@array[0..1]);
foo($array[0], $array[1], $array[2]);
sub foo ($;$$) { print "@_\n" }
foo(@array);
foo(@array[0..1]);
foo($array[0], $array[1], $array[2]);
imprime:
a b c
a b
a b c
3
b
a b c
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.