NOMBRE
perlmod - Módulos Perl (paquetes y tablas de símbolos)
DESCRIPCIÓN
Paquetes
Perl proporciona un mecanismo de espacios de nombres alternativos que evita colisiones entre variables de distintos paquetes. De hecho, en Perl no hay variables globales. La instrucción package
declara que la unidad de compilación está en el espacio de nombres especificado. El ámbito de la declaración de paquete abarca desde la declaración misma hasta el final del bloque, de la función eval
o del archivo actuales, lo que aparezca antes (es el mismo ámbito que el de los operadores my() y local()). Los identificadores dinámicos sin calificar estarán en este espacio de nombres, excepto los pocos identificadores que, de no estar calificados, corresponderán de manera predeterminada al paquete main
en lugar de al actual, como se indica a continuación. Una instrucción package
solo afecta a las variables dinámicas, incluidas aquellas en las que se usa local(); no afecta a las variables léxicas creadas con my(). Normalmente será la primera declaración en un archivo, incluida por medio de los operadores do
, require
o use
. Puede cambiar a un paquete en más de un lugar; esto solo influye en la tabla de símbolos que el compilador usará para el resto del bloque. Puede hacer referencia a variables e identificadores de archivo en otros paquetes usando como prefijo del identificador el nombre del paquete y un doble signo de dos puntos: $Paquete::Variable
. Si se omite el nombre del paquete, se supondrá que es main
. Es decir, $::vela
equivale a $main::vela
.
Anteriormente, el delimitador de paquete era una simple comilla, pero ahora se usa un doble signo de dos puntos, en parte porque es más legible para los humanos y también porque es más legible para las macros de emacs. Además, hace que los programadores de C++ se sientan más cómodos (más que si se usara la comilla, que se parece más al estilo seguido por los programadores de Ada). Puesto que la sintaxis antigua todavía se admite por compatibilidad con las versiones anteriores, si intenta usar una cadena como "Vamos a cenar en $Gino's"
, se accederá a $Gino::s
; es decir, la variable $s del paquete Gino
, que seguramente no sea lo que desea. Use llaves para eliminar ambigüedades: "Vamos a cenar en ${Gino}'s"
.
Los paquetes también pueden contener separadores, como en $EXTERIOR::INTERIOR::var
. Sin embargo, esto no implica nada sobre el orden de búsqueda de los nombres. No hay paquetes relativos: todos los símbolos deben ser locales con respecto al paquete actual o deben aparecer completamente calificados, comenzando por el paquete más externo. Por ejemplo, no hay ningún lugar dentro del paquete EXTERIOR
en el que la variable <$INTERIOR::var> pueda hacer referencia a $EXTERIOR::INTERIOR::var
. INTERIOR
es un paquete global totalmente independiente.
En la tabla de símbolos de un paquete sólo se almacenarán los identificadores que comiencen por letras (o guiones bajos). Todos los demás símbolos se almacenarán en el paquete main
, incluidas todas las variables de puntuación, como $_. Además, cuando no se usan los nombres calificados, los identificadores STDIN, STDOUT, STDERR, ARGV, ARGVOUT, ENV, INC y SIG se almacenan en el paquete main
, incluso cuando se usan para propósitos distintos de los predefinidos. Si tiene un paquete llamado m
, s
o y
, no puede usar la forma calificada de un identificador, ya que podría interpretarse como una detección de patrones, una substitución o una transliteración.
Las variables cuyo nombre comienza con un guión bajo se solían asignar al paquete main
, pero en su día decidimos que para los desarrolladores de paquetes era más útil poder usar guiones bajos iniciales para indicar nombres de variables y métodos privados. Sin embargo, aún se fuerza la asignación al paquete main
de los nombres de variables y funciones con un único guión bajo (_
), como $_ y sub_
. Vea también la sección "La sintaxis de los nombres de variables" de perlvar.
Las cadenas evaluadas con eval
se compilan en el paquete en que se compiló la función eval() (sin embargo, las asignaciones a $SIG{}
suponen que el controlador de señal especificado está en el paquete main
; califique el nombre del controlador de señal si desea que esté en un paquete). En el archivo perldb.pl de la biblioteca de Perl encontrará un ejemplo. Inicialmente cambia al paquete DB
, de forma que el depurador no interfiera con las variables del programa que intenta depurar. Sin embargo, en varios puntos cambia temporalmente al paquete main
para evaluar diversas expresiones en este contexto (o en el contexto en el que esté trabajando). Vea perldebug.
El símbolo especial __PACKAGE__
contiene el paquete actual, pero no puede usarse (fácilmente) para crear nombres de variables.
Vea perlsub para obtener información sobre otras cuestiones relativas al ámbito y relacionadas con my() y local(); vea perlref para obtener información sobre los cierres.
Tabla de símbolos
La tabla de símbolos de un paquete se almacena en el hash cuyo nombre es el nombre del paquete con un doble signo de dos puntos anexado. Así, el nombre de la tabla de símbolos de main
es %main::
, y se puede abreviar como %::
. De la misma forma, el nombre de la tabla de símbolos del paquete anidado mencionado previamente sería %EXTERIOR::INTERIOR::
.
Usamos la notación *nombre
para hacer referencia al valor de cada entrada del hash.
local *main::foo = *main::bar;
Puede usar esto para imprimir todas las variables del paquete, por ejemplo. La biblioteca estándar (aunque anticuada) dumpvar.pl y el módulo Devel::Symdump de CPAN lo usan.
El resultado de crear directamente nuevas entradas en la tabla de símbolos o de modificar cualquier entrada que no sea ya un typeglob no está definido y puede estar sujeto a cambios entre versiones de Perl.
Una asignación a un typeglob realiza una operación de creación de alias. Por ejemplo:
*bea = *beatriz;
hace que las variables, subrutinas, formatos e identificadores de archivos y directorios a los que se accede mediante el identificador beatriz
también sean accesibles mediante bea
. Si desea crear un alias de una sola variable o subrutina específica, debe asignar una referencia:
*bea = \$beatriz;
Esto hace que $beatriz y $bea sean la misma variable; en cambio, @beatriz y @bea son arrays independientes. Es un poco lioso, ¿no?
Existe una sutil diferencia entre las instrucciones siguientes:
*foo = *bar;
*foo = \$bar;
*foo = *bar
hace que los typeglobs sean sinónimos, mientras que *foo = \$bar
hace que las partes escalares de dos typeglobs distintos se refieran al mismo valor escalar. Esto se puede ver en el siguiente ejemplo de código:
$bar = 1;
*foo = \$bar; # Hace que $foo sea un alias de $bar
{
local $bar = 2; # Restringe los cambios al bloque
print $foo; # Imprime '1'
}
Se imprime '1', ya que $foo
contiene una referencia a la variable $bar
original, la que fue reemplazada por local()
y que será restaurada cuando finalice el bloque. Como el acceso a las variables se realiza a través del typeglob, puede usar *foo = *bar
para crear un alias que se pueda localizar (pero tenga en cuenta que esto significa que no puede disponer de @foo
y @bar
independientes, etc.).
Lo que hace que todo esto sea importante es que el módulo Exporter usa alias de expansión como mecanismo de importación/exportación. Una variable exportada de un módulo se podrá localizar adecuadamente o no en función de cómo se haya exportado:
@EXPORT = qw($FOO); # Forma usual; no se puede localizar
@EXPORT = qw(*FOO); # Se puede localizar
Puede evitar el primer caso usando el nombre completo ($Package::FOO
) donde necesite un valor local, o bien reemplazarlo mediante *FOO = *Package::FOO
en el script.
El mecanismo *x = \$y
se puede usar para pasar y devolver referencias sencillas a (o desde) las subrutinas si no desea copiar el valor completo. Sólo funciona al asignar valores a variables dinámicas (no léxicas).
%mi_hash = (); # no puede ser my()
*mi_hash = fn( \%otro_hash );
sub fn {
local *sim_hash = shift;
# ahora use %sim_hash de la forma usual y
# afectará al hash %otro_hash del autor de la llamada
my %nhash = (); # haga lo que desee
return \%nhash;
}
Al volver, la referencia reemplazará la ubicación de hash ocupada en la tabla de símbolos especificada por el typeglob *mi_hash. Esta es una forma poco habitual de pasar referencias de forma sencilla, cuando no se desea tener que recordar cómo desreferenciar variables de forma explícita.
Otro uso de la tabla de símbolos consiste en crear escalares "constantes".
*PI = \3.14159265358979;
Ahora no puede modificar $PI
, lo que probablemente no sea mala idea. Esto no es lo mismo que una subrutina constante, que está sujeta a optimización en tiempo de compilación. Una subrutina constante es una subrutina cuyo prototipo no consume argumentos y devuelve una expresión constante. En perlsub encontrará más información al respecto. El pragma use constant
es una abreviatura adecuada para estos casos.
Puede usar *foo{PACKAGE}
y *foo{NAME}
para averiguar de qué nombre y paquete proviene la entrada *foo de la tabla de símbolos. Esto puede ser útil en una subrutina que recibe typeglobs como argumentos:
sub identificar_typeglob {
my $glob = shift;
print 'Recibí ', *{$glob}{PACKAGE}, '::', *{$glob}{NAME}, "\n";
}
identificar_typeglob *foo;
identificar_typeglob *bar::baz;
Esto imprime
Recibí main::foo
Recibí bar::baz
También se puede usar la notación *foo{COSA}
para obtener referencias a los elementos individuales de *foo. Vea perlref.
Las definiciones de subrutinas (y las definiciones de declaraciones) no tienen por qué ubicarse en el paquete al que pertenece la tabla de símbolos en que aparecen. Es posible definir una subrutina fuera del paquete calificando explícitamente el nombre de la subrutina:
package main;
sub Un_paquete::foo { ... } # &foo definida en Un_paquete
Esto no es más que una forma abreviada de asignación de typeglob en tiempo de compilación:
BEGIN { *Un_paquete::foo = sub { ... } }
y no es lo mismo que escribir:
{
package Un_paquete;
sub foo { ... }
}
En las dos primeras versiones, el cuerpo de la subrutina se define en el paquete main
, no en Un_paquete. De forma que el código siguiente:
package main;
$Un_paquete::nombre = "Pedro";
$main::nombre = "Pablo";
sub Un_paquete::foo {
print "en ", __PACKAGE__, ": \$nombre es '$nombre'\n";
}
Un_paquete::foo();
imprime:
en main: $nombre es 'Pablo'
en lugar de:
en Un_paquete: $nombre es 'Pedro'
Esto también tiene implicaciones para el uso del calificador SUPER:: (vea perlobj).
BEGIN, UNITCHECK, CHECK, INIT y END
Hay cinco bloques de código con un nombre especial que se ejecutan al principio y final de la ejecución de un programa Perl. Son los bloques BEGIN
, UNITCHECK
, CHECK
, INIT
y END
.
Estos bloques de código pueden usarse con el prefijo sub
para dar la apariencia de ser subrutinas (aunque esto no se recomienda). Debe tenerse en cuenta que estos bloques de código no existen realmente como subrutinas con nombres, aunque así lo parezca. Esto es así porque se puede incluir más de uno de estos bloques de código en un programa y todos ellos se ejecutarán en el momento adecuado. Por esta razón no puede ejecutar ninguno de estos bloques usando su nombre.
Un bloque de código BEGIN
se ejecuta tan pronto como es posible, es decir, en el momento en que está completamente definido, incluso antes del análisis del resto del archivo (o cadena) que lo contiene. Es posible disponer de varios bloques BEGIN
en el mismo archivo (o cadena evaluada); se ejecutarán por orden de definición. Puesto que el bloque de código BEGIN
se ejecuta inmediatamente, puede obtener definiciones de subrutinas, etc. de otros archivos a tiempo para que sean visibles en tiempo de compilación y ejecución. Una vez ejecutado el bloque BEGIN
, pasa a estar no definido y el código usado se devuelve al banco de memoria de Perl.
El bloque de código END
se ejecuta tan tarde como sea posible, es decir, una vez que Perl ha finalizado la ejecución del programa y justo antes de que se produzca la salida del intérprete, incluso si la salida se debe a la ejecución de la función die() (esto no ocurre si se transforma en otro programa mediante exec
o si se desencadena por una señal; el código debe encargarse de capturar esta señal, si es posible). Puede disponer de múltiples bloques END
en un mismo archivo; se ejecutarán en orden inverso al de la definición: es decir, siguiendo el orden "primero en llegar, último en salir" (LIFO, last in, first out). Los bloques END
no se ejecutarán si se inicia perl con el modificador -c
o si se produce un error de compilación.
Tenga en cuenta que los bloques de código END
no se ejecutan al final de una evaluación eval()
de cadena: si se crea un bloque END
mediante una función eval()
de cadena, se ejecutará como cualquier otro bloque END
del mismo paquete en orden LIFO, justo antes de que se produzca la salida del intérprete.
Dentro de un bloque de código END
, $?
contiene el valor que el programa va a pasar a exit()
. Puede modificar $?
para cambiar el valor de salida del programa. Evite cambiar $?
accidentalmente (por ejemplo, ejecutando algo mediante system
).
Dentro de un bloque END
, el valor de ${^GLOBAL_PHASE}
es "END"
.
Los bloques UNITCHECK
, CHECK
e INIT
son útiles para capturar la transición entre la fase de compilación y la de ejecución del programa principal.
Los bloques UNITCHECK
se ejecutan inmediatamente después de que se haya compilado la unidad que los definió. El archivo del programa principal y cada módulo que carga son unidades de compilación, como lo son las funciones eval
de cadena, el código compilado con la construcción (?{ })
en una expresión regular, las llamadas a do ARCHIVO
, require ARCHIVO
y el código que haya a continuación del modificador -e
en la línea de comandos.
Los bloques BEGIN
y UNITCHECK
no están directamente relacionados con la fase del intérprete. Se pueden crear y ejecutar en cualquier fase.
Los bloques de código CHECK
se ejecutan inmediatamente después de que finalice la fase inicial de compilación de Perl y antes de que comience el tiempo de ejecución, en orden LIFO. Los bloques de código CHECK
se usan en el compilador de Perl para guardar el estado compilado del programa.
Dentro de un bloque CHECK
, el valor de ${^GLOBAL_PHASE}
es "CHECK"
.
Los bloques INIT
se ejecutan justo antes de iniciar el tiempo de ejecución de Perl, en orden "primero en entrar, primero en salir " (FIFO, first in, first out).
Dentro de un bloque INIT
el valor de ${^GLOBAL_PHASE}
será "INIT"
.
Los bloques CHECK
e INIT
en código compilado por require
y en funciones do
o eval
de cadena no se ejecutarán si están después del final de la fase principal de compilación; esto puede suponer un problema en el entorno mod_perl y otros entornos permanentes que usan esas funciones para cargar código en tiempo de ejecución.
Cuando se usan los modificadores -n y -p en Perl, BEGIN
y END
funcionan como lo harían en awk, es decir, como un caso degenerado. Los bloques BEGIN
y CHECK
se ejecutan cuando se usa el modificador -c para llevar a cabo únicamente una compilación de comprobación de la sintaxis, aunque no se ejecute el código principal.
El programa begincheck expone esto de forma clara (o eso esperamos):
#!/usr/bin/perl
# begincheck
print "10. El código normal se ejecuta en tiempo de ejecución.\n";
END { print "16. Y este cuento se ha acabado.\n" }
INIT { print " 7. Los bloques INIT se ejecutan en orden FIFO antes del tiempo de ejecución.\n" }
UNITCHECK {
print " 4. Y, por tanto, antes que los bloques CHECK.\n"
}
CHECK { print " 6. Esta es la sexta línea.\n" }
print "11. Por supuesto, se ejecuta por orden.\n";
BEGIN { print " 1. Los bloques BEGIN se ejecutan en orden FIFO durante la compilación.\n" }
END { print "15. Lea perlmod para obtener más información.\n" }
CHECK { print " 5. Los bloques CHECK se ejecutan en orden LIFO tras la compilación.\n" }
INIT { print " 8. Volvemos a ejecutar esto, ahora con el modificador -c de perl.\n" }
print "12. Esto es lo contrario de código ofuscado.\n";
END { print "14. Los bloques END se ejecutan en orden LIFO al finalizar.\n" }
BEGIN { print " 2. Así que esta línea será la segunda.\n" }
UNITCHECK {
print " 3. Los bloques UNITCHECK se ejecutan en orden LIFO tras compilar cada archivo.\n"
}
INIT { print " 9. Verá la diferencia inmediatamente.\n" }
print "13. Parece lioso, pero no lo es en realidad.\n";
__END__
Clases en Perl
No hay una sintaxis especial para clases en Perl, pero un paquete puede actuar como una clase si proporciona subrutinas que se comportan como métodos. Un paquete así también pueden derivar alguno de sus métodos de otra clase (paquete) especificando el nombre de este paquete en su array global @ISA, que debe ser una variable global (no léxica) del paquete.
Encontrará más información en perlootut y perlobj.
Módulos Perl
Un módulo no es más que un conjunto de funciones relacionadas y ubicadas en un archivo de biblioteca, es decir, un paquete Perl con el mismo nombre que el archivo. Está diseñado específicamente para que otros módulos o programas lo puedan reutilizar. Para ello puede proporcionar un mecanismo que exporte algunos de sus símbolos a la tabla de símbolos de cualquier paquete que lo use, o puede funcionar como una definición de clase y hacer que su semántica esté disponible implícitamente mediante llamadas a métodos de la clase y sus objetos, sin exportar nada de forma explícita. También se pueden combinar ambos mecanismos.
Por ejemplo, para empezar a desarrollar un módulo tradicional, no orientado a objetos, llamado Mi::Modulo, cree el archivo Mi/Modulo.pm y use esta plantilla:
package Mi::Modulo; # se supone que está en Mi/Modulo.pm
use strict;
use warnings;
BEGIN {
require Exporter;
# establecer la versión para la comprobación de versión
our $VERSION = 1.00;
# heredar de Exporter para exportar funciones y variables
our @ISA = qw(Exporter);
# funciones y variables que se exportan de forma predeterminada
our @EXPORT = qw(func1 func2);
# funciones y variables que se exportan de forma opcional
our @EXPORT_OK = qw($Var1 %Hash1 func3);
}
# las variables globales de paquete exportadas van aquí
our $Var1 = '';
our %Hash1 = ();
# las variables globales de paquete no exportadas van aquí
# (son accesibles mediante $Mi::Modulo::cosa)
our @otras = ();
our $cosa = '';
# las variables léxicas privadas del archivo van aquí, antes que las funciones que las usan
my $var_priv = '';
my %hash_secreto = ();
# aquí va una función privada del archivo, como cierre
# puede llamarse mediante $func_priv->();
my $func_priv = sub {
...
};
# incorpore todas sus funciones, exportadas o no;
# no olvide poner algo interesante entre {}
sub func1 { ... }
sub func2 { ... }
# esta no se exporta, pero puede llamarse directamente
# mediante Mi::Modulo::func3()
sub func3 { ... }
END { ... } # el código de limpieza del módulo va aquí (destructor global)
1; # no olvide devolver un valor verdadero desde este archivo
A continuación, puede declarar y usar sus variables en funciones sin calificarlas. Vea Exporter y perlmodlib para obtener más información sobre los mecanismos y las cuestiones de estilo de la creación de módulos.
Para incluir un módulo Perl en un programa, escriba
use Modulo;
o bien
use Modulo LISTA;
Eso equivale exactamente a
BEGIN { require 'Modulo.pm'; 'Modulo'->import; }
o bien
BEGIN { require 'Modulo.pm'; 'Modulo'->import(LISTA); }
Como un caso especial
use Modulo ();
equivale exactamente a
BEGIN { require 'Modulo.pm'; }
Todos los archivos de módulo Perl tienen la extensión .pm. El operador use
lo tiene en cuenta, para que no tenga que escribir "Modulo.pm" entre comillas. Esto también ayuda a distinguir los módulos nuevos de los antiguos, que usaban la extensión .pl o .ph. Para los nombres de los módulos se utiliza mayúscula inicial en cada palabra, a no ser que funcionen como pragmas (que en realidad son directivas del compilador, y a veces se denominan "módulos pragmáticos" o incluso "pragmata", si lo suyo es el latín).
Las dos instrucciones
require MiModulo;
require "MiModulo.pm";
difieren en dos aspectos. En el primer caso, si el nombre del módulo contiene el símbolo "::" (por ejemplo, Mi::Modulo
), dicho símbolo se traducirá como el separador de directorios habitual (generalmente "/"). En el segundo caso no es así, y debe especificarse de forma literal. La otra diferencia consiste en que require
indica al compilador que se usa la sintaxis indirecta de objetos en relación a "MiModulo", de forma que las expresiones del estilo $ob = purge MiModulo
indican llamadas a métodos y no llamadas a funciones. (Sí, esto realmente puede suponer una diferencia).
Como la instrucción use
implica la presencia de un bloque BEGIN
, la importación de semántica tiene lugar tan pronto como se haya compilado la instrucción use
, antes de que se compile el resto del archivo. Esto es lo que permite a un módulo funcionar como un mecanismo pragma y declarar subrutinas que están visibles incluso como operadores de lista o unarios para el resto del archivo actual. Pero no funcionará si usa require
en lugar de use
. Con require
puede producirse el siguiente problema:
require Cwd; # hace Cwd:: accesible
$directorio = Cwd::getcwd();
use Cwd; # importa nombres de Cwd::
$directorio = getcwd();
require Cwd; # hace Cwd:: accesible
$directorio= getcwd(); # vaya... no existe main::getcwd()
En general se recomienda usar use Module ()
en lugar de require Module
, ya que determina la disponibilidad del módulo en tiempo de compilación, y no durante la ejecución del programa. Puede producirse una excepción cuando dos módulos intentan usarse mutuamente mediante use
y a la vez cada uno llama a una función del otro módulo. En este caso debe usarse require
.
Los paquetes Perl pueden anidarse dentro de otros nombres de paquete, por lo que los nombres de paquete pueden contener ::
. Pero si se usa ese nombre de paquete directamente como nombre de archivo, la manipulación de este nombre de archivo podría resultar difícil (o incluso imposible) en otros sistemas. Así, si el nombre del módulo es, por ejemplo, Text::Soundex
, su definición se ubicará en el archivo de biblioteca Text/Soundex.pm.
Los módulos Perl siempre tienen un archivo .pm, pero podrían tener asociados otros ejecutables vinculados dinámicamente (normalmente con la extensión .so) o definiciones de subrutinas cargadas automáticamente (normalmente con extensión .al). Si es así, esto será completamente transparente para el usuario del módulo. El archivo .pm debe encargarse de cargar cualquier funcionalidad adicional (o producir la carga automática). Por ejemplo, aunque el módulo POSIX realiza tanto carga dinámica como carga automática, el usuario solo tiene que escribir use POSIX
para obtenerlo todo.
Crear módulos seguros para hilos de ejecución
En la versión 5.6.0 de Perl se agregó compatibilidad con un nuevo tipo de hilos de ejecución, denominado hilos de ejecución de intérprete (ithreads). Estos hilos de ejecución se pueden usar de forma explícita e implícita.
Los hilos de ejecución de intérprete clonan el árbol de datos de forma que no haya datos compartidos entre distintos hilos de ejecución. Estos hilos de ejecución pueden usarse con el módulo threads
o bien ejecutando fork() en win32 (en realidad, una simulación de fork()). Cuando se clona un hilo de ejecución, se clonan también todos los datos de Perl. Sin embargo, los datos que no pertenecen a Perl no se pueden clonar automáticamente. Desde la versión 5.7.2 de Perl se incluye la subrutina especial CLONE
. CLONE
le permite hacer todo lo que necesite, como controlar la clonación de datos que no sean de Perl, si es necesario. Se llamará a CLONE
como método de clase una vez por cada paquete en el que esté definido (o que lo herede). Se llamará en el contexto del nuevo hilo de ejecución, de forma que todas las modificaciones se realizarán en el nuevo espacio. Actualmente se llama a CLONE
sin más parámetros que el nombre del paquete que llama, pero esto podría cambiar; es probable que en el futuro se pasen parámetros adicionales para proporcionar más información sobre el estado de la clonación.
Si desea ejecutar CLONE
sobre todos los objetos tendrá que hacer un seguimiento de los objetos correspondientes a cada paquete. Esto se hace de forma sencilla mediante un hash y Scalar::Util::weaken().
En la versión 5.8.7 de Perl se incluyó la subrutina especial CLONE_SKIP
. Al igual que en el caso de CLONE
, se llama a CLONE_SKIP
una vez por paquete; sin embargo, en el caso de esta última, se llama justo antes de que comience la clonación, y en el contexto del hilo de ejecución primario. Si devuelve un valor verdadero, no se clonarán objetos de esa clase; o más bien, se copiarán como valores undef no bendecidos. Por ejemplo; si en el hilo primario hay dos referencias a un hash bendecido, en el hilo derivado habrá dos referencias a un valor escalar no definido. Esto proporciona un mecanismo sencillo para hacer que los hilos de ejecución de los módulos sean seguros; basta con agregar sub CLONE_SKIP { 1 }
al comienzo de la clase y se llamará a DESTROY()
una sola vez por cada objeto. Si el hilo derivado tuviera que usar los objetos, sería necesario un enfoque más sofisticado.
Al igual que en el caso de CLONE
, el único parámetro usado en las llamadas a CLONE_SKIP
es el nombre del paquete que llama, aunque esto podría cambiar. De forma análoga, y teniendo en cuenta posibles ampliaciones futuras, el valor devuelto debería ser un solo valor 0
ó 1
.
VEA TAMBIÉN
En perlmodlib encontrará información sobre cuestiones generales de estilo relacionadas con la creación de módulos y clases en Perl, así como descripciones de la biblioteca estándar y de CPAN; vea Exporter para conocer cómo funciona el mecanismo estándar de exportación/importación; en perlootut y perlobj encontrará información detallada sobre la creación de clases; vea perlobj para obtener información de referencia sobre objetos; en perlsub podrá obtener información sobre cuestiones relacionadas con las funciones y el ámbito; por último, vea también perlxstut y perlguts, donde encontrará más detalles sobre la programación de módulos de extensión.
TRADUCTORES
Manuel Gómez Olmedo
Joaquín Ferrero (Tech Lead)
Enrique Nell (Language Lead)