Problem w tym, że prototypy funkcji Perla nie robią tego, co ludzie myślą, że robią. Ich celem jest umożliwienie pisania funkcji, które będą analizowane jak funkcje wbudowane Perla.
Przede wszystkim wywołania metod całkowicie ignorują prototypy. Jeśli robisz programowanie obiektowe, nie ma znaczenia, jaki prototyp mają Twoje metody. (Więc nie powinni mieć żadnego prototypu.)
Po drugie, prototypy nie są ściśle egzekwowane. Jeśli wywołasz podprogram za pomocą &function(...)
, prototyp jest ignorowany. Więc tak naprawdę nie zapewniają żadnego bezpieczeństwa typu.
Po trzecie, są upiorną akcją na odległość. (Szczególnie $
prototyp, który powoduje, że odpowiedni parametr jest oceniany w kontekście skalarnym, zamiast domyślnego kontekstu listy).
W szczególności utrudniają przekazywanie parametrów z tablic. Na przykład:
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]);
wydruki:
a b c
a b
a b c
3
b
a b c
wraz z 3 ostrzeżeniami o main::foo() called too early to check prototype
(jeśli ostrzeżenia są włączone). Problem polega na tym, że tablica (lub wycinek tablicy) obliczona w kontekście skalarnym zwraca długość tablicy.
Jeśli potrzebujesz napisać funkcję działającą jak wbudowana, użyj prototypu. W przeciwnym razie nie używaj prototypów.
Uwaga: Perl 6 będzie miał całkowicie odnowione i bardzo przydatne prototypy. Ta odpowiedź dotyczy tylko Perla 5.