Página 1 de 1

require en CGI

NotaPublicado: 2009-08-25 03:40 @195
por davidferrero
Buenas de nuevo. Vuelvo a la carga con otra pregunta por desconocimiento y que a priori debería ser sencilla.

El caso es el siguiente: tengo un pequeño formulario en HTML el cual trato de gestionar mediante un CGI. Hasta ahí sin problemas. El caso es que dentro de este formulario me gustaría incluir funciones escritas en otros scripts. En principio no tiene problemas para cargar los scripts mediante require pero luego cuando le llamo a la función me da error y no me reconoce la ruta del script.

Este sería el código:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. BEGIN{
  2.     my $curr_path = $0;
  3.     eval{
  4.         $curr_path=~ s/html\/gestion_formulario\.cgi//;
  5.         require "${curr_path}lib/script.pl";
  6.     } or print "Error loading libraries: \n $@" if ($@);
  7. } # BEGIN
  8.  
  9. # Después llamo a la función
  10. &funcion_script(); # Realiza la actualización de un fichero
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4


El error que me muestra es:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
undefined subroutine &main::funcion_script called at directorio donde se encuentra el CGI line 10
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4

Re: require en CGI

NotaPublicado: 2009-08-25 03:55 @205
por explorer
El require importa el fichero, pero no importa el espacio de nombres del módulo. Por eso el nombre de la función no es conocida.

Debes hacer un import después del require, con el nombre de las funciones del módulo que quieres usar.

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
import 'funcion_script';
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Quizás te sea mucho más fácil hacer un do():

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
do "${curr_path}lib/script.pl";
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Más información en use().

Re: require en CGI

NotaPublicado: 2009-08-25 05:31 @271
por davidferrero
He probado lo que me dices pero resulta que me sigue dando error, pero seguramente por que no lo escribo bien,

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. require "${curr_path}/lib/MONITOR.pl";
  2. import 'getHTML';
  3.  
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


y el mensaje que me da es
String found where operator expected...
(Do you need to predeclare import?)

He visto el enlace a use pero no me funciona tampoco y además tiene distinta sintaxis, Utiliza
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1.  require MODULO;
  2. Modulo -> import (LIST);
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Que tampoco me funciona.

Re: require en CGI

NotaPublicado: 2009-08-25 05:58 @290
por explorer
Un ejemplo sencillo con do(). Si tenemos este código que almacena la subrutinas
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
#!/usr/bin/perl

sub getHTML {
    return "<html><body>Hola</body></body>\n";
}
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

podemos importarlo a nuestro programa con do():
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
#!/usr/bin/perl
use strict;
use warnings;
use diagnostics;

do 'subrutinas.pl';

print getHTML();
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Si lo hiciéramos como un módulo, sería
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
#!/usr/bin/perl

package subrutinas;

sub getHTML {
    return "<html><body>Hola</body></body>\n";
}

1;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
Ahora, el espacio de nombres está dentro de "subrutinas", así que debemos cambiar la forma de hacer la llamada:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
#!/usr/bin/perl
use strict;
use warnings;
use diagnostics;

use subrutinas;

print subrutinas::getHTML();
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Pero claro, eso es escribir mucho. Nosotros quisiéramos escribir solamente getHTML. Para eso, debemos importar ese nombre de función a nuestro espacio de nombres. El proceso lleva varios pasos (crear una función llamada import() y más cosas), por lo que lo más cómodo es usar el módulo Exporter:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
#!/usr/bin/perl

package subrutinas;

require Exporter;
@ISA = qw(Exporter);    # Estos dos líneas equivalen a: use Exporter 'import';

@EXPORT = ('&getHTML');

sub getHTML {
    return "<html><body>Hola</body></body>\n";
}

1;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
Y ahora ya podemos llamar a nuestra función directamente:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
#!/usr/bin/perl
use strict;
use warnings;
use diagnostics;

use subrutinas;

print getHTML();
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

En el caso de que no queramos que esta importación suceda en tiempo de compilación, usaremos require:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
#!/usr/bin/perl
use strict;
use warnings;
use diagnostics;

require subrutinas;
subrutinas->import('getHTML');

print getHTML();
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Más información en perlmod y perlmodlib

Re: require en CGI

NotaPublicado: 2009-08-25 06:07 @296
por davidferrero
Vale gracias, me convence más la última porque es la opción que más seria me parece, así que si tengo algún problema ya volveré, jejeje

Re: require en CGI

NotaPublicado: 2009-08-25 07:27 @352
por explorer
Jeje... sí, parece seria, pero al final, un require hace un do():
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
sub require {
    my ($filename) = @_;
    if (exists $INC{$filename}) {
        return 1 if $INC{$filename};
        die "Compilation failed in require";
    }
    my ($realfilename,$result);
    ITER: {
        foreach $prefix (@INC) {
            $realfilename = "$prefix/$filename";
            if (-f $realfilename) {
                $INC{$filename} = $realfilename;
                $result = do $realfilename;      # <=== carga del fichero
                last ITER;
            }
        }
        die "Can't find $filename in \@INC";
    }
    if ($@) {
        $INC{$filename} = undef;
        die $@;
    } elsif (!$result) {
        delete $INC{$filename};
        die "$filename did not return true value";
    } else {
        return $result;
    }
}
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

(extraído de la documentación de require.