• Publicidad

archivo con funciones aparte

Así que programas sin strict y las expresiones regulares son otro modo de hablar. Aquí encontrarás respuestas de nivel avanzado, no recomendable para los débiles de corazón.

archivo con funciones aparte

Notapor Leibvitz » 2005-08-13 10:53 @495

Hola! No sé si este es el mejor sitio para escribir estas linias. Mi intención es tener un programa prinicpal en un archivo y tener ciertas funciones un otro y otras en otro. Como lo debería hacer? Es necesario crear un módulo? En el programa principal hay handles de sockets, se pueden usar en los archivos aparte? Algo de orientación por favor.

Gracias.
Nam nunc tempus est.
Avatar de Usuario
Leibvitz
Perlero nuevo
Perlero nuevo
 
Mensajes: 6
Registrado: 2004-11-07 13:19 @596
Ubicación: Reus, Catalunya

Publicidad

Notapor kidd » 2005-08-13 11:59 @541

Hola:

Una de las grandes ventajas que tienes en perl son los módulos. Es decir puedes encapsular tu código en diferentes archivos, haciendo una mejor organización de tu código y haciendolo más mantenible.

El chiste de todo esto que es puedas crear código reusable, es decir si hay una función que repites una y otra vez en todo el código, entonces lo mejor es que hagas una subrutina y ya no tengas que estar repitiendo código.

Aquí te dejo unos links que te pueden servir de base:
http://perlmonks.org/?node_id=102347
http://perlmonks.org/?node_id=431702


SALUDOS
Uriel Lizama Perl programmer fundador de Perl en Español
Perl Programming Language
Avatar de Usuario
kidd
Creador de Perl en Español
Creador de Perl en Español
 
Mensajes: 1166
Registrado: 2003-10-15 16:52 @744
Ubicación: México

Re: archivo con funciones aparte

Notapor Joaquin » 2005-08-13 12:02 @543

No es necesario hacer un módulo para dividir un programa en partes.
El método más sencillo para incorporar funciones definidas en otros archivos perl es importarlas con el operador do o con el require.
Por ejemplo, tenemos este código con una función definida:
Código: Seleccionar todo
# funciones.pl
sub pinta
{
    my $nombre = shift;
    print "Hola $nombre\n";
}
1;
Sólo tiene una función, que necesita un parámetro. Luego, tenemos un programa que necesita esa función:
Código: Seleccionar todo
#!/usr/bin/perl
require 'funciones.pl';
my $nombre = "Leibvitz";
&pinta($nombre);
Se podía haber usado 'do' en vez de 'require', pero este último hace un chequeo de errores, provoca una excepción si no encuentra el fichero, no es capaz de compilar el código perl o si después de hacerlo algún código de inicialización devuelve un valor que no sea positivo (por eso el fichero acaba en un 1; )
De todas formas, hacer un módulo es fácil:
Módulo Funciones.pm:
Código: Seleccionar todo
package Funciones;
sub pinta
{
    my $nombre = shift;
    print "Hola $nombre\n";
}
1;
Programa:
Código: Seleccionar todo
#!/usr/bin/perl
use Funciones;
Funciones::pinta("Leibvitz");
O importando los nombres de las funciones dentro de tu programa:
Módulo Funciones.pm:
Código: Seleccionar todo
package Funciones;
use Exporter;
@ISA = ('Exporter');
@EXPORT = qw( &pinta );
sub pinta
{
    my $nombre = shift;
    print "Hola $nombre\n";
}
1;
Programa:
Código: Seleccionar todo
#!/usr/bin/perl
use Funciones;
pinta("Leibvitz");
Joaquin
 

Notapor Leibvitz » 2005-08-13 16:28 @728

Entendido. Me ha quedado muy claro. Gracias.

Si tengo un handle de socket debería pasarlo por parametro para usarlo en las funciones del módulo o el archivo aparte, no?
Nam nunc tempus est.
Avatar de Usuario
Leibvitz
Perlero nuevo
Perlero nuevo
 
Mensajes: 6
Registrado: 2004-11-07 13:19 @596
Ubicación: Reus, Catalunya

Re: archivo con funciones aparte

Notapor Perl user » 2005-08-13 22:20 @972

Joaquin escribiste:No es necesario hacer un módulo para dividir un programa en partes.
El método más sencillo para incorporar funciones definidas en otros archivos perl es importarlas con el operador do o con el require.
Por ejemplo, tenemos este código con una función definida:

En realidad un módulo sigue siendo cualquier componente reutilizable extra ( puede ser interno o externo) del cual puedes importar símbolos, ignorando si es con require o use.

Joaquin escribiste:Sólo tiene una función, que necesita un parámetro. Luego, tenemos un programa que necesita esa función:
Código: Seleccionar todo
#!/usr/bin/perl
require 'funciones.pl';
my $nombre = "Leibvitz";
&pinta($nombre);
Se podía haber usado 'do' en vez de 'require', pero este último hace un chequeo de errores, provoca una excepción si no encuentra el fichero, no es capaz de compilar el código perl o si después de hacerlo algún código de inicialización devuelve un valor que no sea positivo (por eso el fichero acaba en un 1; )

El uso de &func( params ) creo que ya lo había comentado anteriormente en el foro, ha sido descalificado desde Perl 5.003, por qué? No permite el uso de prototipos, hace mas oscuro el código, y el uso de &func hace uso de la misma @_. Sin embargo goto &func o \&func es otro rollo. &func también puede servirte sólo cuando lo usas en conjunto con defined.
No es buen estilo. Déjalo para Perl4.

Joaquin escribiste:De todas formas, hacer un módulo es fácil:
Módulo Funciones.pm:
Código: Seleccionar todo
package Funciones;
sub pinta
{
    my $nombre = shift;
    print "Hola $nombre\n";
}
1;
Programa:
Código: Seleccionar todo
#!/usr/bin/perl
use Funciones;
Funciones::pinta("Leibvitz");
O importando los nombres de las funciones dentro de tu programa:
Módulo Funciones.pm:
Código: Seleccionar todo
package Funciones;
use Exporter;
@ISA = ('Exporter');
@EXPORT = qw( &pinta );
sub pinta
{
    my $nombre = shift;
    print "Hola $nombre\n";
}
1;
Programa:
Código: Seleccionar todo
#!/usr/bin/perl
use Funciones;
pinta("Leibvitz");

Bueno tomando en cuenta que ya te mencioné lo malo de usar '&func', el ejemplo es bueno, sin embargo, creo se te olvidó explicar ( a menos que no haya sido tu intención inicial ) qué es lo que use hace internamente.

use simplemente ofrece lo siguiente:
    - Los módulos son verificados en tiempo de compilación, a diferencia de require/do, que son en tiempo de ejecución, por lo tanto la falta de módulos y algunos otros fallos en compile-time, pueden ser atrapados directamente con use.
    - En conjunto con eval puede permitirte el name mapping y otras técnicas en tiempo de ejecución.
    - Lo que use realiza detrás de las cámaras es:
    Código: Seleccionar todo
    use Mi::Modulo;

    es tratado como:
    Código: Seleccionar todo
    BEGIN {
       require Mi::Modulo;
       import Mi::Modulo;
    }

    Es decir, hace la carga del módulo, e importará al espacio de nombres actual los símbolos que dicho módulo importe por default según indicado en Exporter.
    Sin embargo, cuando usamos:
    Código: Seleccionar todo
    use Mi::Modulo qw( foo bar baz);

    lo que normalmente quiere decir Perl es:
    Código: Seleccionar todo
    BEGIN {
       require Mi::Modulo;
       import Mi::Modulo qw( foo bar baz );
    }

    es decir, importa los símbolos foo bar y baz a nuestro espacio de nombres.
    y el uso de:
    Código: Seleccionar todo
    use Mi::Modulo ();

    es convertido a:
    Código: Seleccionar todo
    BEGIN { require Mi::Modulo; }

Como podrán observar, el comportamiento al usar use es mucho mas seguro que require/do. :)

El trabajo de Exporter lo dejaremos para luego que hablemos de la tabla de símbolos y los typeglobs. :)

Saludos,

NOTA: mas referencias en perlmod y perlmodlib.
Marco A. Manzo
[email protected]
http://www.unixmonkeys.com/amnesiac/
Perl Programming Language
Perl user
Maestro honorario
Maestro honorario
 
Mensajes: 271
Registrado: 2004-11-03 21:11 @924

Re: archivo con funciones aparte

Notapor Joaquin » 2005-08-16 07:46 @365

Perl user escribiste:El uso de &func( params ) creo que ya lo había comentado anteriormente en el foro, ha sido descalificado desde Perl 5.003, por qué? No permite el uso de prototipos, hace mas oscuro el código, y el uso de &func hace uso de la misma @_. Sin embargo goto &func o \&func es otro rollo. &func también puede servirte sólo cuando lo usas en conjunto con defined.
No es buen estilo. Déjalo para Perl4.

Efecticamente. He vuelto a releer el perlsyn 5.8.7 y el uso de '&' queda relegado al goto. Pero mira lo que pone en el perlsub 5.8.7:
A subroutine may be called using an explicit "&" prefix. The "&" is optional in modern Perl, as are parentheses if the subroutine has been predeclared. The "&" is not optional when just naming the
subroutine, such as when it's used as an argument to defined() or undef(). Nor is it optional when you want to do an indirect subroutine call with a subroutine name or reference using the "&$subref()"
or "&{$subref}()" constructs, although the "$subref->()" notation solves that problem. See perlref for more about all that.

Subroutines may be called recursively. If a subroutine is called using the "&" form, the argument list is optional, and if omitted, no @_ array is set up for the subroutine: the @_ array at the time
of the call is visible to subroutine instead. This is an efficiency mechanism that new users may wish to avoid.

&foo(1,2,3); # pass three arguments
foo(1,2,3); # the same

foo(); # pass a null list
&foo(); # the same

&foo; # foo() get current args, like foo(@_) !!
foo; # like foo() IFF sub foo predeclared, else "foo"

Not only does the "&" form make the argument list optional, it also disables any prototype checking on arguments you do provide. This is partly for historical reasons, and partly for having a conve-
nient way to cheat if you know what you're doing. See Prototypes below.

En resumen:
    El uso de '&' es opcional si la subrutina ha sido declarada antes.
    No es opcional cuando se utiliza como argumento a funciones como defined() y undef() o en una llamada indirecta, como en &$referenciaAsubrutina() o &{$referenciaAsubrutina}().
    El uso de '&' hace pasar el actual valor de @_ como argumento, lo cual puede ser cómodo, pero a su vez olvida la definición dada en el prototipado
Entonces queda claro que no hay nada mejor que leer y volver a leer la documentación...
Joaquin
 


Volver a Avanzado

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 2 invitados