Das Problem ist, dass Perls Funktionsprototypen nicht das tun, was die Leute denken. Sie sollen es Ihnen ermöglichen, Funktionen zu schreiben, die wie die integrierten Funktionen von Perl analysiert werden.
Erstens ignorieren Methodenaufrufe Prototypen vollständig. Wenn Sie OO-Programmierung durchführen, spielt es keine Rolle, welchen Prototyp Ihre Methoden haben. (Sie sollten also keinen Prototyp haben.)
Zweitens werden Prototypen nicht strikt durchgesetzt. Wenn Sie eine Unterroutine mit aufrufen &function(...)
, wird der Prototyp ignoriert. Sie bieten also keine wirkliche Sicherheit.
Drittens sind sie gruselig auf Distanz. (Insbesondere der $
Prototyp, bei dem der entsprechende Parameter im skalaren Kontext anstelle des Standardlistenkontexts ausgewertet wird.)
Insbesondere erschweren sie die Übergabe von Parametern aus Arrays. Beispielsweise:
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]);
Drucke:
a b c
a b
a b c
3
b
a b c
zusammen mit 3 Warnungen über main::foo() called too early to check prototype
(wenn Warnungen aktiviert sind). Das Problem ist, dass ein im skalaren Kontext ausgewertetes Array (oder Array-Slice) die Länge des Arrays zurückgibt.
Wenn Sie eine Funktion schreiben müssen, die sich wie eine integrierte Funktion verhält, verwenden Sie einen Prototyp. Verwenden Sie andernfalls keine Prototypen.
Hinweis: Perl 6 wird komplett überarbeitet und sehr nützliche Prototypen haben. Diese Antwort gilt nur für Perl 5.