W innym pytaniu o przepełnienie stosu Leon Timmermans zapewnił:
Radziłbym nie używać prototypów. Mają swoje zastosowania, ale nie w większości przypadków i na pewno nie w tym.
Dlaczego to może być prawda (lub inaczej)? Prawie zawsze dostarczam prototypy moich funkcji Perla i nigdy wcześniej nie widziałem nikogo, kto powiedziałby coś złego na temat ich używania.
Odpowiedzi:
Prototypy nie są złe, jeśli są prawidłowo używane. Trudność polega na tym, że prototypy Perla nie działają tak, jak ludzie często tego oczekują. Osoby z doświadczeniem w innych językach programowania zwykle oczekują, że prototypy zapewnią mechanizm sprawdzania poprawności wywołań funkcji: to znaczy, że mają odpowiednią liczbę i typ argumentów. Prototypy Perla nie nadają się do tego zadania. To nadużycie jest złe. Prototypy Perla mają jeden i bardzo różny cel:
Prototypy pozwalają zdefiniować funkcje, które zachowują się jak funkcje wbudowane.
Na przykład możesz zdefiniować taką funkcję:
i nazwij to jako
bez konieczności pisania,
\
aby pobrać odwołanie do tablicy.Krótko mówiąc, prototypy pozwalają stworzyć własny cukier syntaktyczny. Na przykład framework Moose używa ich do emulacji bardziej typowej składni OO.
Jest to bardzo przydatne, ale prototypy są bardzo ograniczone:
Zobacz Prototypy w perlsubie, aby poznać wszystkie krwawe szczegóły.
źródło
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:
wydruki:
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.
źródło
foo()
print 2, ponieważ jest to ostatni element w Twoim wycinku z dwoma elementami. Zmień na,my @array = qw(foo bar baz)
a zobaczysz różnicę. (Tak na marginesie, dlatego nie inicjuję tablic / list w sekwencjach liczbowych opartych na 0 lub 1 w wyrzuconym, demonstracyjnym kodzie. Pomieszanie indeksów, liczników i elementów w kontekstach ugryzło mnie więcej niż raz. Głupie, ale prawdziwe.)a b c
Twój punkt widzenia.Zgadzam się z powyższymi dwoma plakatami. Generalnie
$
należy unikać używania . Prototypy są użyteczne tylko przy użyciu argumentów bloku (&
) globs (*
) lub prototypy odniesienia (\@
,\$
,\%
,\*
)źródło
($)
prototyp tworzy nazwany operator jednoargumentowy, który może być przydatny (z pewnością Perl uzna je za przydatne; ja też czasami). Po drugie, przy nadpisywaniu wbudowanych (czy to przez import, czy przy użyciu CORE :: GLOBAL: :), powinieneś ogólnie trzymać się dowolnego prototypu, który miał wbudowany, nawet jeśli zawiera on a$
, lub możesz zaskoczyć programistę (siebie, parzysty) z kontekstem listowym, gdzie w przeciwnym razie funkcja wbudowana zapewniłaby kontekst skalarny.Niektórzy ludzie, patrząc na prototyp podprogramu Perl, myślą, że oznacza coś, czego nie robi:
Dla Perla oznacza to, że parser oczekuje dwóch argumentów. W ten sposób Perl pozwala ci tworzyć podprogramy zachowujące się jak wbudowane, z których wszystkie wiedzą, czego się spodziewać po kolejnym kodzie. Możesz przeczytać o prototypach w perlsub
Bez czytania dokumentacji ludzie domyślają się, że prototypy odnoszą się do sprawdzania argumentów w czasie wykonywania lub czegoś podobnego, co widzieli w innych językach. Jak w przypadku większości rzeczy, które ludzie domyślają się o Perlu, okazują się one błędne.
Jednak począwszy od Perla v5.20, Perl ma funkcję, eksperymentalną w chwili, gdy to piszę, która daje coś bardziej podobnego do tego, czego oczekują użytkownicy i czego. PerlaPodprogramy zliczają argumenty w czasie wykonywania, przypisują zmienne i ustawiają domyślne:
Jest to funkcja, której prawdopodobnie potrzebujesz, jeśli rozważasz prototypy.
źródło