O problema é que os protótipos de função do Perl não fazem o que as pessoas pensam que fazem. Seu propósito é permitir que você escreva funções que serão analisadas como as funções integradas do Perl.
Em primeiro lugar, as chamadas de método ignoram completamente os protótipos. Se você estiver fazendo programação OO, não importa o protótipo de seus métodos. (Portanto, eles não devem ter nenhum protótipo.)
Em segundo lugar, os protótipos não são estritamente impostos. Se você chamar uma sub-rotina com &function(...)
, o protótipo será ignorado. Portanto, eles não fornecem nenhum tipo de segurança.
Terceiro, eles são uma ação assustadora à distância. (Especialmente o $
protótipo, que faz com que o parâmetro correspondente seja avaliado no contexto escalar, em vez do contexto de lista padrão.)
Em particular, eles dificultam a passagem de parâmetros de arrays. Por exemplo:
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]);
estampas:
a b c
a b
a b c
3
b
a b c
junto com 3 avisos sobre main::foo() called too early to check prototype
(se os avisos estiverem habilitados). O problema é que uma matriz (ou fatia de matriz) avaliada no contexto escalar retorna o comprimento da matriz.
Se você precisar escrever uma função que atue como embutida, use um protótipo. Caso contrário, não use protótipos.
Nota: Perl 6 terá protótipos completamente renovados e muito úteis. Essa resposta se aplica apenas ao Perl 5.