Sab Ago 13, 2005 9:53 am
|
 |
Leibvitz
Perlero Nuevo

|
Registrado: 07 Nov 2004
Mensajes: 11
Ubicación: Reus, Catalunya
|
|
| archivo con funciones aparte |
|
|
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. |
|
|
|

Sab Ago 13, 2005 10:59 am
|
 |
kidd
Creador de Perl en Español

|
Registrado: 15 Oct 2003
Mensajes: 1389
Ubicación: México
|
|
|
|
|
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 |
|

Sab Ago 13, 2005 11:02 am
|
 |
Joaquin
Perlero Nuevo

|
Registrado: 13 Ago 2005
Mensajes: 12
Ubicación: Valladolid, España
|
|
| Re: archivo con funciones aparte |
|
|
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: |
# 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: |
#!/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: |
package Funciones;
sub pinta
{
my $nombre = shift;
print "Hola $nombre\n";
}
1; |
Programa:
| Código: |
#!/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: |
package Funciones;
use Exporter;
@ISA = ('Exporter');
@EXPORT = qw( &pinta );
sub pinta
{
my $nombre = shift;
print "Hola $nombre\n";
}
1; |
Programa:
| Código: |
#!/usr/bin/perl
use Funciones;
pinta("Leibvitz"); |
|
|

Sab Ago 13, 2005 3:28 pm
|
 |
Leibvitz
Perlero Nuevo

|
Registrado: 07 Nov 2004
Mensajes: 11
Ubicación: Reus, Catalunya
|
|
|
|
|
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? |
|

Sab Ago 13, 2005 9:20 pm
|
 |
Perl user
Maestro Honorario

|
Registrado: 03 Nov 2004
Mensajes: 385
|
|
| Re: archivo con funciones aparte |
|
|
| Joaquin escribió: | 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 escribió: |
Sólo tiene una función, que necesita un parámetro. Luego, tenemos un programa que necesita esa función:
| Código: |
#!/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 escribió: |
De todas formas, hacer un módulo es fácil:
Módulo Funciones.pm:
| Código: |
package Funciones;
sub pinta
{
my $nombre = shift;
print "Hola $nombre\n";
}
1; |
Programa:
| Código: |
#!/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: |
package Funciones;
use Exporter;
@ISA = ('Exporter');
@EXPORT = qw( &pinta );
sub pinta
{
my $nombre = shift;
print "Hola $nombre\n";
}
1; |
Programa:
| Código: |
#!/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:
es tratado como:
| Código: |
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: |
use Mi::Modulo qw( foo bar baz);
|
lo que normalmente quiere decir Perl es:
| Código: |
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: |
use Mi::Modulo ();
|
es convertido a:
| Código: |
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. |
|

Mar Ago 16, 2005 6:46 am
|
 |
Joaquin
Perlero Nuevo

|
Registrado: 13 Ago 2005
Mensajes: 12
Ubicación: Valladolid, España
|
|
| Re: archivo con funciones aparte |
|
|
| Perl user escribió: | 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:
| Cita: | 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... |
|

Powered by phpBB © 2001, 2005 phpBB Group
|