En otra pregunta de Stack Overflow, Leon Timmermans afirmó:
Te aconsejo que no uses prototipos. Tienen sus usos, pero no en la mayoría de los casos y definitivamente no en este.
¿Por qué podría ser esto cierto (o no)? Casi siempre proporciono prototipos para mis funciones de Perl, y nunca antes había visto a nadie decir nada malo sobre su uso.
Respuestas:
Los prototipos no son malos si se usan correctamente. La dificultad es que los prototipos de Perl no funcionan como la gente espera que lo hagan. Las personas con experiencia en otros lenguajes de programación tienden a esperar que los prototipos proporcionen un mecanismo para verificar que las llamadas a funciones sean correctas: es decir, que tengan el número y tipo de argumentos correctos. Los prototipos de Perl no son adecuados para esta tarea. Es el mal uso que es malo. Los prototipos de Perl tienen un propósito singular y muy diferente:
Los prototipos le permiten definir funciones que se comportan como funciones integradas.
Por ejemplo, podría definir una función como esta:
y llámalo como
sin necesidad de escribir el
\
para tomar una referencia a la matriz.En pocas palabras, los prototipos le permiten crear su propio azúcar sintáctico. Por ejemplo, el marco de Moose los usa para emular una sintaxis OO más típica.
Esto es muy útil pero los prototipos son muy limitados:
Vea Prototipos en perlsub para todos los detalles sangrientos.
fuente
El problema es que los prototipos de funciones de Perl no hacen lo que la gente cree que hacen. Su propósito es permitirle escribir funciones que se analizarán como las funciones integradas de Perl.
En primer lugar, las llamadas a métodos ignoran por completo los prototipos. Si está haciendo programación OO, no importa qué prototipo tengan sus métodos. (Por lo que no deberían tener ningún prototipo).
En segundo lugar, los prototipos no se aplican estrictamente. Si llama a una subrutina con
&function(...)
, el prototipo se ignora. Por lo que realmente no brindan ningún tipo de seguridad.En tercer lugar, son acciones espeluznantes a distancia. (Especialmente el
$
prototipo, que hace que el parámetro correspondiente se evalúe en contexto escalar, en lugar del contexto de lista predeterminado).En particular, dificultan el paso de parámetros desde matrices. Por ejemplo:
huellas dactilares:
junto con 3 advertencias sobre
main::foo() called too early to check prototype
(si las advertencias están habilitadas). El problema es que una matriz (o porción de matriz) evaluada en contexto escalar devuelve la longitud de la matriz.Si necesita escribir una función que actúe como una incorporada, use un prototipo. De lo contrario, no utilice prototipos.
Nota: Perl 6 tendrá prototipos completamente renovados y muy útiles. Esta respuesta se aplica solo a Perl 5.
fuente
foo()
prints 2 porque ese es el elemento final en su segmento de dos elementos. Cambie amy @array = qw(foo bar baz)
y verá la diferencia. (Aparte, esta es la razón por la que no inicializo matrices / listas en secuencias numéricas basadas en 0 o 1 en código demostrativo desechable. La confusión entre índices, recuentos y elementos en contextos me ha mordido más de una vez. Tonto pero cierto.)a b c
para aclarar tu punto.Estoy de acuerdo con los dos carteles anteriores. En general,
$
debe evitarse su uso. Los prototipos son sólo es útil cuando se utiliza argumentos de bloque (&
), pegotes (*
), o prototipos de referencia (\@
,\$
,\%
,\*
)fuente
($)
prototipo crea un operador unario con nombre, que puede ser útil (ciertamente Perl los encuentra útiles; yo también, en ocasiones). En segundo lugar, al anular las incorporaciones (ya sea a través de la importación o utilizando CORE :: GLOBAL: :), en general debería ceñirse a cualquier prototipo que tuviera la incorporada, incluso si eso incluye a$
, o podría sorprender al programador (usted mismo, incluso) con contexto de lista donde el integrado proporcionaría contexto escalar.Algunas personas, al mirar un prototipo de subrutina de Perl, creen que significa algo que no significa:
Para Perl, eso significa que el analizador espera dos argumentos. Es la forma de Perl de permitirle crear subrutinas que se comportan como integradas, todas las cuales saben qué esperar del código subsiguiente. Puedes leer sobre prototipos en perlsub
Sin leer la documentación, la gente adivina que los prototipos se refieren a la verificación de argumentos en tiempo de ejecución o algo similar que han visto en otros lenguajes. Como ocurre con la mayoría de las cosas que la gente adivina sobre Perl, resultan estar equivocadas.
Sin embargo, comenzando con Perl v5.20, Perl tiene una característica, experimental mientras escribo esto, que brinda algo más parecido a lo que los usuarios esperan y qué. Las firmas de subrutinas de Perl ejecutan el recuento de argumentos en tiempo, la asignación de variables y la configuración predeterminada:
Esta es la característica que probablemente desee si está considerando prototipos.
fuente