• Publicidad

Error en la llamada a una función

¿Ya sabes lo que es una referencia? Has progresado, el nível básico es cosa del pasado y ahora estás listo para el siguiente nivel.

Error en la llamada a una función

Notapor aalleexx81 » 2009-05-07 12:09 @547

Éste es el error:
Código: Seleccionar todo
main::CambDirCas() called too early to check prototype at ./usugrupo.pl line 83.


No entiendo exactamente lo que me quiere indicar. Supuse que era por no declarar el prototipo de la función antes de la llamada, pero luego caí en que en este lenguaje da exactamente igual si lo haces antes o después. Si alguien puede orientarme se lo agradeceré mucho.

Saludos.
aalleexx81
Perlero nuevo
Perlero nuevo
 
Mensajes: 11
Registrado: 2009-05-04 15:21 @681

Publicidad

Notapor explorer » 2009-05-07 13:27 @602

El aviso sale porque:

1.- Están activados los superpoderes 'strict' y 'warnings'

2.- Has definido la función después de que aparezca su uso a lo largo del programa

3.- La definición de función incluye el prototipado.

Si usas el superpoder 'diagnostics', entonces sale una explicación más larga:

Código: Seleccionar todo
    (W prototype) You've called a function that has a prototype before the
    parser saw a definition or declaration for it, and Perl could not check
    that the call conforms to the prototype.  You need to either add an
    early prototype declaration for the subroutine in question, or move the
    subroutine definition ahead of the call to get proper prototype
    checking.  Alternatively, if you are certain that you're calling the
    function correctly, you may put an ampersand before the name to avoid
    the warning.  See perlsub.

que quiere decir:
Código: Seleccionar todo
    (A prototipo) Ha llamado a una función que tiene un prototipo antes de
    que el intérprete viera la definición o declaración de ella, y Perl no
    puede comprobar si la llamada es conforme al prototipo. Necesita, o bien,
    añadir una declaración con prototipo previa para la subrutina en cuestión,
    o mover la definición de la subrutina por delante de la llamada, para
    que funcione apropiadamente la comprobación del prototipo. De otra forma,
    si está seguro de que llama a la función de forma correcta, puede poner
    un ampersand delante del nombre para cancelar esta alerta. Vea perlsub


Ejemplo, si tenemos el código
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
#!/usr/bin/perl
use strict;
use warnings;
use diagnostics;

sub funcion($) {
    print "Hola $_[0]\n";
}

funcion('amigo');
Coloreado en 0.007 segundos, usando GeSHi 1.0.8.4
no habrá ningún problema: perl (el intérprete), encuentra la definición de funcion() antes de ser usada, por lo que sabe que solo admitirá un valor escalar ($).

Ahora bien, si invertimos la posición:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
#!/usr/bin/perl
use strict;
use warnings;
use diagnostics;

funcion('amigo');

sub funcion($) {
    print "Hola $_[0]\n";
}
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
el programa funcionará, pero explotará por acción de los superpoderes 'strict' y 'warnings'. Y 'diagnostics' nos soltará el rollo anterior.

Primera solución: Poner el prototipo antes
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
#!/usr/bin/perl
use strict;
use warnings;
use diagnostics;

sub funcion($);            # <===== Declaración de función

funcion('amigo');

sub funcion($) {           # <===== Definición de función
    print "Hola $_[0]\n";
}
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4

El problema, aquí, es que tienes que acordarte de mantener iguales las líneas de la declaración y la definición, en lo que se refiere al prototipo.

Si, por ejemplo, pones en la declaración
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
sub funcion($$);
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
el programa terminará con el aviso Prototype mismatch: sub main::funcion ($$) vs ($). Vamos, que no coinciden:
Código: Seleccionar todo
    (S prototype) The subroutine being declared or defined had previously been
    declared or defined with a different function prototype.

Código: Seleccionar todo
    (S prototipo) La subrutina declarada o definida ha sido declarada o definida
    con un prototipo de función diferente.


Segunda solución: Poner un '&' delante del nombre de función
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
#!/usr/bin/perl
use strict;
use warnings;
use diagnostics;

&funcion('amigo');

sub funcion ($) {
    print "Hola $_[0]\n";
}
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
Y ya está.

El único inconveniente... es que el código se vuelve más "peludo". Aparte de tener que acordarte de poner el dichoso carácter.

Tercera solución: No usar prototipos
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
#!/usr/bin/perl
use strict;
use warnings;
use diagnostics;

funcion('amigo');

sub funcion {
    print "Hola $_[0]\n";
}
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Sí, ya sabemos que los prototipos nos pueden ayudar para comprobar los argumentos pasados e incluso facilitan el paso de argumentos complejos... Además, facilita escribir funciones de forma más "libre":
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
#!/usr/bin/perl
use strict;
use warnings;
use diagnostics;

sub funcion($);

funcion 'amigo';

sub funcion($) {
    print "Hola $_[0]\n";
}
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
(fíjate que hemos podido quitar los paréntesis, porque perl sabe cuántos y cómo son los argumentos de funcion()).

Pero, en situaciones simples, lo más simple, funciona: no usarlos.

Más información en perldoc perlsub, Prototipos.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14486
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Error en la llamada a una función

Notapor aalleexx81 » 2009-05-07 13:57 @623

Muchas gracias
aalleexx81
Perlero nuevo
Perlero nuevo
 
Mensajes: 11
Registrado: 2009-05-04 15:21 @681


Volver a Intermedio

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 1 invitado

cron