Il problema è che i prototipi di funzioni di Perl non fanno quello che la gente pensa di fare. Il loro scopo è quello di consentire di scrivere funzioni che verranno analizzate come le funzioni integrate di Perl.
Prima di tutto, le chiamate ai metodi ignorano completamente i prototipi. Se stai facendo programmazione OO, non importa quale prototipo hanno i tuoi metodi. (Quindi non dovrebbero avere alcun prototipo.)
Secondo, i prototipi non vengono applicati rigorosamente. Se chiami una subroutine con &function(...)
, il prototipo viene ignorato. Quindi in realtà non forniscono alcuna protezione dai tipi.
Terzo, sono azioni spettrali a distanza. (Soprattutto il $
prototipo, che fa sì che il parametro corrispondente venga valutato nel contesto scalare, invece del contesto dell'elenco predefinito.)
In particolare, rendono difficile il passaggio di parametri dagli array. Per esempio:
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]);
stampe:
a b c
a b
a b c
3
b
a b c
insieme a 3 avvisi su main::foo() called too early to check prototype
(se gli avvisi sono abilitati). Il problema è che un array (o slice di array) valutato in contesto scalare restituisce la lunghezza dell'array.
Se hai bisogno di scrivere una funzione che agisca come un built-in, usa un prototipo. Altrimenti, non utilizzare prototipi.
Nota: Perl 6 avrà prototipi completamente rinnovati e molto utili. Questa risposta si applica solo a Perl 5.