GoGPT Best VPN GoSearch

icono de página de OnWorks

perlsub - Online en la nube

Ejecute perlsub en el proveedor de alojamiento gratuito de OnWorks a través de Ubuntu Online, Fedora Online, emulador en línea de Windows o emulador en línea de MAC OS

Este es el comando perlsub que se puede ejecutar en el proveedor de alojamiento gratuito de OnWorks utilizando una de nuestras múltiples estaciones de trabajo en línea gratuitas, como Ubuntu Online, Fedora Online, emulador en línea de Windows o emulador en línea de MAC OS.

PROGRAMA:

NOMBRE


perlsub - subrutinas Perl

SINOPSIS


Para declarar subrutinas:

sub NAME; # Una declaración "hacia adelante".
sub NOMBRE (PROTO); # ídem, pero con prototipos
sub NOMBRE: ATTRS; # con atributos
sub NOMBRE (PROTO): ATTRS; # con atributos y prototipos

sub NAME BLOCK # Una declaración y una definición.
sub NAME (PROTO) BLOCK # ídem, pero con prototipos
sub NAME (SIG) BLOCK # con una firma en su lugar
sub NAME: ATTRS BLOCK # con atributos
sub NAME (PROTO): ATTRS BLOCK # con prototipos y atributos
sub NOMBRE (SIG): ATTRS BLOQUE # con una firma y atributos

Para definir una subrutina anónima en tiempo de ejecución:

$ subref = sub BLOQUE; # sin proto
$ subref = sub (PROTO) BLOQUE; # con proto
$ subref = sub (SIG) BLOQUE; # con firma
$ subref = sub: ATTRS BLOCK; # con atributos
$ subref = sub (PROTO): ATTRS BLOCK; # con proto y atributos
$ subref = sub (SIG): ATTRS BLOCK; # con firma y atributos

Para importar subrutinas:

use MODULE qw (NAME1 NAME2 NAME3);

Para llamar subrutinas:

LISTA DE NOMBRES); # & es opcional entre paréntesis.
LISTA DE NOMBRES; # Los paréntesis son opcionales si están predeclarados / importados.
&LISTA DE NOMBRES); # Evitar prototipos.
&NOMBRE; # Hace que el @_ actual sea visible para la subrutina llamada.

DESCRIPCIÓN


Como muchos lenguajes, Perl proporciona subrutinas definidas por el usuario. Estos pueden estar ubicados
en cualquier lugar del programa principal, cargado desde otros archivos a través de "hacer", "requerir" o "usar"
palabras clave, o generadas sobre la marcha usando "eval" o subrutinas anónimas. Usted puede incluso
llamar a una función indirectamente usando una variable que contenga su nombre o una referencia de CÓDIGO.

El modelo de Perl para la llamada de función y los valores de retorno es simple: todas las funciones se pasan como
parámetros una sola lista plana de escalares, y todas las funciones también vuelven a su
llamador una sola lista plana de escalares. Cualquier matriz o hash en estas llamadas y devoluciones
las listas se colapsarán y perderán sus identidades, pero siempre puede usar el paso por referencia
en lugar de evitar esto. Ambas listas de llamadas y devoluciones pueden contener tantos o tan pocos escalares
elementos que desee. (A menudo se llama a una función sin una declaración de retorno explícita
una subrutina, pero realmente no hay diferencia desde la perspectiva de Perl).

Todos los argumentos pasados ​​aparecen en la matriz @_. (También pueden aparecer en léxico
variables introducidas por una firma; consulte "Firmas" a continuación). Por lo tanto, si llamó a un
función con dos argumentos, estos se almacenarían en $ _ [0] y $ _ [1]. La matriz @_ es una
matriz local, pero sus elementos son alias de los parámetros escalares reales. En
En particular, si se actualiza un elemento $ _ [0], se actualiza el argumento correspondiente (o un
se produce un error si no es actualizable). Si un argumento es una matriz o un elemento hash que
no existía cuando se llamó a la función, ese elemento se crea solo cuando (y si)
se modifica o se toma una referencia a él. (Algunas versiones anteriores de Perl crearon el
elemento, ya sea que el elemento haya sido asignado o no.) Asignación a toda la matriz @_
elimina ese alias y no actualiza ningún argumento.

Se puede usar una instrucción "return" para salir de una subrutina, especificando opcionalmente la devolución
valor, que se evaluará en el contexto apropiado (lista, escalar o vacío)
dependiendo del contexto de la llamada de subrutina. Si no especifica ningún valor de retorno, el
subrutina devuelve una lista vacía en el contexto de la lista, el valor indefinido en el contexto escalar,
o nada en contexto vacío. Si devuelve uno o más agregados (matrices y hashes),
estos se aplanarán juntos en una gran lista indistinguible.

Si no se encuentra "retorno" y si la última declaración es una expresión, se devuelve su valor.
Si la última instrucción es una estructura de control de bucle como un "foreach" o un "while", el
el valor devuelto no está especificado. El sub vacío devuelve la lista vacía.

Aparte de una instalación experimental (consulte "Firmas" a continuación), Perl no ha nombrado
parámetros formales. En la práctica, todo lo que debe hacer es asignarlos a una lista "my ()". Variables
que no se declaran privadas son variables globales. Para obtener detalles sangrientos sobre la creación
variables privadas, consulte "Variables privadas a través de mi()"y" Valores temporales a través de local()".
Para crear entornos protegidos para un conjunto de funciones en un paquete separado (y
probablemente un archivo separado), vea "Paquetes" en perlmod.

Ejemplo:

submáx {
my $ max = turno (@_);
foreach $ foo (@_) {
$ max = $ foo si $ max <$ foo;
}
return $ max;
}
$ bestday = max ($ lun, $ tue, $ mié, $ jue, $ vie);

Ejemplo:

# obtener una línea, combinando líneas de continuación
# que comienzan con espacios en blanco

sub get_line {
$ thisline = $ lookahead; # ¡variables globales!
LINE: while (definido ($ lookahead = )) {
if ($ lookahead = ~ / ^ [\ t] /) {
$ thisline. = $ lookahead;
}
else {
Última línea;
}
}
return $ thisline;
}

$ lookahead = ; # obtener la primera línea
while (definido ($ línea = get_line ())) {
...
}

Asignar a una lista de variables privadas para nombrar sus argumentos:

sub mayset {
my ($ clave, $ valor) = @_;
$ Foo {$ clave} = $ valor a menos que $ Foo {$ clave};
}

Debido a que la asignación copia los valores, esto también tiene el efecto de convertir llamada por
referencia en llamada por valor. De lo contrario, una función puede realizar modificaciones in situ
de @_ y cambiar los valores de su llamador.

upcase_in ($ v1, $ v2); # esto cambia $ v1 y $ v2
subupcase_in {
para (@_) {tr / az / AZ /}
}

No se le permite modificar constantes de esta manera, por supuesto. Si un argumento fuera
en realidad literal e intentaste cambiarlo, tomarías una excepción (presumiblemente fatal).
Por ejemplo, esto no funcionará:

upcase_in ("frederick");

Sería mucho más seguro si la función "upcase_in ()" fuera escrita para devolver una copia de su
parámetros en lugar de cambiarlos en su lugar:

($ v3, $ v4) = upcase ($ v1, $ v2); # esto no cambia $ v1 y $ v2
sub mayúscula {
volver a menos que se defina wantarray; # contexto vacío, no hagas nada
mi @parms = @_;
para (@parms) {tr / az / AZ /}
volver wantarray? @parms: $ parms [0];
}

Observe cómo a esta función (sin prototipo) no le importa si se le pasaron escalares reales o
matrices. Perl ve todos los argumentos como una lista grande, larga y plana de parámetros en @_. Este es uno
área donde brilla el estilo simple de paso de argumentos de Perl. La función "upcase ()"
funcionan perfectamente bien sin cambiar la definición de "upcase ()" incluso si lo alimentamos con cosas
Me gusta esto:

@newlist = upcase (@ list1, @ list2);
@newlist = upcase (split /: /, $ var);

Sin embargo, no se sienta tentado a hacer esto:

(@a, @b) = mayúscula (@ list1, @ list2);

Al igual que la lista de parámetros entrantes aplanada, la lista de devolución también se aplasta al regresar.
Entonces, todo lo que ha logrado hacer aquí es almacenar todo en @ay hacer que @b esté vacío. Ver
"Pasar por referencia" para conocer las alternativas.

Se puede llamar a una subrutina usando un prefijo "&" explícito. El "&" es opcional en la versión moderna
Perl, al igual que los paréntesis si la subrutina ha sido declarada previamente. El "&" es No opcional
al nombrar la subrutina, como cuando se usa como argumento para definido () or
undef (). Tampoco es opcional cuando desea hacer una llamada indirecta a subrutina con un
nombre de subrutina o referencia usando las construcciones "& $ subref ()" o "& {$ subref} ()", aunque
la notación "$ subref -> ()" resuelve ese problema. Consulte perlref para obtener más información al respecto.

Las subrutinas se pueden llamar de forma recursiva. Si se llama a una subrutina mediante el formulario "&",
La lista de argumentos es opcional y, si se omite, no se configura ninguna matriz @_ para la subrutina:
La matriz @_ en el momento de la llamada es visible para la subrutina. Esta es una eficiencia
mecanismo que los nuevos usuarios pueden desear evitar.

& foo (1,2,3); # pasar tres argumentos
foo (1,2,3, XNUMX, XNUMX); # lo mismo

foo (); # pasar una lista nula
& foo (); # lo mismo

& foo; # foo () obtiene argumentos actuales, como foo (@_) !!
foo; # como foo () IFF sub foo predeclarado, de lo contrario "foo"

La forma "&" no solo hace que la lista de argumentos sea opcional, sino que también deshabilita cualquier prototipo.
comprobar los argumentos que proporciona. Esto se debe en parte a razones históricas y en parte
por tener una forma conveniente de hacer trampa si sabes lo que estás haciendo. Ver "Prototipos"
abajo.

Desde Perl 5.16.0, el token "__SUB__" está disponible en "use feature 'current_sub'" y
"use 5.16.0". Evaluará una referencia al subwoofer que se está ejecutando actualmente, lo que permite
para llamadas recursivas sin saber el nombre de su subrutina.

utilizar 5.16.0;
my $ factorial = sub {
mi ($ x) = @_;
devuelve 1 si $ x == 1;
return ($ x * __SUB __-> ($ x - 1));
};

El comportamiento de "__SUB__" dentro de un bloque de código de expresiones regulares (como "/(?{...})/") está sujeto a
a través del cambio.

Las subrutinas cuyos nombres están en mayúsculas están reservadas para el núcleo de Perl, al igual que
módulos cuyos nombres están en minúsculas. Una subrutina en todas las mayúsculas es un
convención, lo que significa que será llamado indirectamente por el propio sistema de tiempo de ejecución, generalmente debido
a un evento desencadenado. Las subrutinas cuyo nombre comienza con un paréntesis izquierdo también son
reservado de la misma manera. La siguiente es una lista de algunas subrutinas que actualmente
cosas especiales y predefinidas.

documentado más adelante en este documento
"AUTOLOAD"

documentado en perlmod
"CLONE", "CLONE_SKIP",

documentado en perlobj
"DESTRUIR"

documentado en perltie
"BINMODE", "CLEAR", "CLOSE", "DELETE", "DESTROY", "EOF", "EXISTS", "EXTEND", "FETCH",
"FETCHSIZE", "FILENO", "FIRSTKEY", "GETC", "NEXTKEY", "OPEN", "POP", "PRINT",
"PRINTF", "PUSH", "READ", "READLINE", "SCALAR", "SEEK", "SHIFT", "SPLICE", "STORE",
"STORESIZE", "TELL", "TIEARRAY", "TIEHANDLE", "TIEHASH", "TIESCALAR", "UNSHIFT",
"DESATAR", "ESCRIBIR"

documentado en PerlIO :: via
"BINMODE", "CLEARERR", "CLOSE", "EOF", "ERROR", "FDOPEN", "FILENO", "FILL", "FLUSH",
"OPEN", "POPPED", "PUSHED", "READ", "SEEK", "SETLINEBUF", "SYSOPEN", "TELL", "UNREAD",
"UTF8", "ESCRIBIR"

documentado en perlfunc
"importar", "no importar", "INC"

documentado en UNIVERSAL
"VERSIÓN"

documentado en perldebguts
"DB :: DB", "DB :: sub", "DB :: lsub", "DB :: goto", "DB :: pospuesto"

indocumentado, utilizado internamente por la función de sobrecarga
cualquiera que comience con "("

Las subrutinas "BEGIN", "UNITCHECK", "CHECK", "INIT" y "END" no son tanto
subrutinas como bloques de código especial con nombre, de los cuales puede tener más de uno en un
paquete, y que puedes No llamar explícitamente. Consulte "BEGIN, UNITCHECK, CHECK, INIT y
END "en perlmod

Signatures
ADVERTENCIA: Las firmas de subrutinas son experimentales. La función puede modificarse o eliminarse
en futuras versiones de Perl.

Perl tiene una facilidad experimental para permitir que los parámetros formales de una subrutina sean
introducido por una sintaxis especial, separada del código de procedimiento del cuerpo de la subrutina.
La lista de parámetros formales se conoce como firma. La instalación debe habilitarse primero
una declaración pragmática, "use feature 'signatures'", y producirá una advertencia a menos que
la categoría de advertencias "experimentales :: firmas" está desactivada.

La firma es parte del cuerpo de una subrutina. Normalmente, el cuerpo de una subrutina es simplemente
un bloque de código entre corchetes. Cuando se usa una firma, la firma es una lista entre paréntesis
que va inmediatamente después del nombre de la subrutina (o, para las subrutinas anónimas,
inmediatamente después de la palabra clave "sub"). La firma declara variables léxicas que son
en el alcance del bloque. Cuando se llama a la subrutina, la firma toma el control primero.
Completa las variables de firma de la lista de argumentos que se pasaron. Si el
La lista de argumentos no cumple con los requisitos de la firma, entonces arrojará un
excepción. Cuando se completa el procesamiento de la firma, el control pasa al bloque.

Los parámetros posicionales se manejan simplemente nombrando variables escalares en la firma. Para
ejemplo,

sub foo ($ izquierda, $ derecha) {
return $ izquierda + $ derecha;
}

toma dos parámetros posicionales, que deben completarse en tiempo de ejecución con dos argumentos. Por
Por defecto, los parámetros son obligatorios y no se permite pasar más argumentos de los
esperado. Entonces lo anterior es equivalente a

subfoo {
die "Demasiados argumentos para la subrutina" a menos que @_ <= 2;
muere "Muy pocos argumentos para la subrutina" a menos que @_> = 2;
mi $ izquierda = $ _ [0];
mi $ derecha = $ _ [1];
return $ izquierda + $ derecha;
}

Se puede ignorar un argumento omitiendo la parte principal del nombre de un parámetro
declaración, dejando sólo un sigilo "$" desnudo. Por ejemplo,

sub foo ($ primero, $, $ tercero) {
return "primero = $ primero, tercero = $ tercero";
}

Aunque el argumento ignorado no entra en una variable, sigue siendo obligatorio para el
llamador para pasarlo.

Un parámetro posicional se hace opcional dando un valor predeterminado, separado del
nombre de parámetro por "=":

sub foo ($ izquierda, $ derecha = 0) {
return $ izquierda + $ derecha;
}

La subrutina anterior se puede llamar con uno o dos argumentos. El valor predeterminado
La expresión se evalúa cuando se llama a la subrutina, por lo que puede proporcionar diferentes valores predeterminados.
valores para diferentes llamadas. Solo se evalúa si el argumento se omitió realmente.
de la llamada. Por ejemplo,

my $ auto_id = 0;
sub foo ($ cosa, $ id = $ auto_id ++) {
print "$ cosa tiene ID $ id";
}

asigna automáticamente identificaciones secuenciales distintas a cosas para las que no se proporcionó ninguna identificación
llamador. Una expresión de valor predeterminado también puede referirse a parámetros anteriores en el
firma, haciendo que el valor predeterminado de un parámetro varíe de acuerdo con los parámetros anteriores.
Por ejemplo,

sub foo ($ primer_nombre, $ apellido, $ apodo = $ primer_nombre) {
print "$ first_name $ apellido se conoce como \" $ nickname \ "";
}

Un parámetro opcional puede ser anónimo al igual que un parámetro obligatorio. Por ejemplo,

sub foo ($ cosa, $ = 1) {
imprimir $ cosa;
}

El valor predeterminado del parámetro aún se evaluará si el argumento correspondiente no es
suministrado, aunque el valor no se almacenará en ningún lugar. Esto es en caso de evaluarlo.
tiene efectos secundarios importantes. Sin embargo, se evaluará en un contexto nulo, por lo que si
no tiene efectos secundarios y no es trivial, generará una advertencia si el "vacío"
La categoría de advertencia está habilitada. Si el valor predeterminado de un parámetro opcional sin nombre no es
importante, puede omitirse tal como el nombre del parámetro era:

sub foo ($ cosa, $ =) {
imprimir $ cosa;
}

Los parámetros posicionales opcionales deben ir después de todos los parámetros posicionales obligatorios. (Si
No hay parámetros posicionales obligatorios, entonces se pueden establecer parámetros posicionales opcionales.
lo primero en la firma.) Si hay varios parámetros posicionales opcionales
y no se proporcionan suficientes argumentos para completarlos todos, se completarán de izquierda a
tenía razón.

Después de los parámetros posicionales, se pueden capturar argumentos adicionales en un parámetro slurpy.
La forma más simple de esto es solo una variable de matriz:

sub foo ($ filter, @inputs) {
imprimir $ filtro -> ($ _) foreach @inputs;
}

Con un parámetro slurpy en la firma, no hay límite superior en la cantidad de argumentos
se puede pasar. Un parámetro de matriz slurpy puede no tener nombre al igual que un parámetro posicional,
en cuyo caso su único efecto es desactivar el límite de argumento que de otro modo
aplicar:

sub foo ($ cosa, @) {
imprimir $ cosa;
}

En cambio, un parámetro slurpy puede ser un hash, en cuyo caso los argumentos disponibles son
interpretado como claves y valores alternos. Debe haber tantas claves como valores: si
hay un argumento extraño, entonces se lanzará una excepción. Las claves se encadenarán y
si hay duplicados, la última instancia tiene prioridad sobre la anterior, como con
construcción hash estándar.

sub foo ($ filter,% entradas) {
imprimir $ filtro -> ($ _, $ entradas {$ _}) para cada clave de clasificación% entradas;
}

Un parámetro de hash slurpy puede no tener nombre al igual que otros tipos de parámetros. Todavía
insiste en que el número de argumentos disponibles sea uniforme, aunque no
ser puesto en una variable.

sub foo ($ cosa,%) {
imprimir $ cosa;
}

Un parámetro slurpy, ya sea una matriz o un hash, debe ser lo último en la firma. Puede
seguir los parámetros posicionales obligatorios y opcionales; también puede ser lo único en el
firma. Los parámetros slurpy no pueden tener valores predeterminados: si no se proporcionan argumentos para
ellos entonces obtienes una matriz vacía o un hash vacío.

Una firma puede estar completamente vacía, en cuyo caso todo lo que hace es verificar que la persona que llama
no pasó argumentos:

subfoo() {
123 regresar;
}

Cuando se usa una firma, los argumentos aún están disponibles en la variable de matriz especial
@_, además de las variables léxicas de la firma. Hay una diferencia entre
las dos formas de acceder a los argumentos: @_ alias los argumentos, pero la firma
las variables obtienen copias de los argumentos. Entonces, escribir en una variable de firma solo cambia
esa variable, y no tiene ningún efecto en las variables de la persona que llama, pero escribir en un elemento de
@_ modifica lo que la persona que llama usó para proporcionar ese argumento.

Existe una posible ambigüedad sintáctica entre firmas y prototipos (ver
"Prototipos"), porque ambos comienzan con un paréntesis de apertura y ambos pueden aparecer en algunos
de los mismos lugares, como justo después del nombre en una declaración de subrutina. Para
razones históricas, cuando las firmas no están habilitadas, cualquier paréntesis de apertura en tal
El contexto desencadenará un análisis sintáctico de prototipos muy indulgente. La mayoría de las firmas serán
interpretados como prototipos en esas circunstancias, pero no serán prototipos válidos. (Un válido
prototipo no puede contener ningún carácter alfabético.) Esto conducirá a un poco confuso
error de mensajes.

Para evitar ambigüedades, cuando las firmas están habilitadas, la sintaxis especial para prototipos es
discapacitado. No se intenta adivinar si un grupo entre paréntesis estaba destinado a ser un
prototipo o una firma. Para dar un prototipo a una subrutina en estas circunstancias, utilice
un atributo de prototipo. Por ejemplo,

sub foo: prototipo ($) {$ _ [0]}

Es completamente posible que una subrutina tenga tanto un prototipo como una firma. Ellos
hacer diferentes trabajos: el prototipo afecta la compilación de llamadas a la subrutina, y el
la firma coloca los valores de los argumentos en variables léxicas en tiempo de ejecución. Por lo tanto, puede escribir

sub foo ($ izquierda, $ derecha): prototipo ($$) {
return $ izquierda + $ derecha;
}

El atributo del prototipo y cualquier otro atributo vienen después de la firma.

Privado Variables vía mi()
Sinopsis:

my $ foo; # declarar $ foo léxicamente local
mi (@wid,% get); # declarar lista de variables locales
my $ foo = "flurp"; # declare $ foo léxico e inícielo
mi @oof = @bar; # declare @oof léxico e inícielo
my $ x: Foo = $ y; # similar, con un atributo aplicado

ADVERTENCIA: El uso de listas de atributos en "mis" declaraciones todavía está evolucionando. La corriente
la semántica y la interfaz están sujetas a cambios. Ver atributos y Attribute :: Handlers.

El operador "my" declara que las variables enumeradas se limitan léxicamente al
bloque, condicional ("si / a menos que / elsif / más"), bucle ("para / foreach / mientras / hasta / continuar"),
subrutina, "eval" o "do / require / use" 'archivo. Si aparece más de un valor, el
La lista debe estar entre paréntesis. Todos los elementos enumerados deben ser valores legales. Solamente
Los identificadores alfanuméricos pueden tener un alcance léxico: incorporaciones mágicas como $ / must actualmente
ser "local" izado con "local" en su lugar.

A diferencia de las variables dinámicas creadas por el operador "local", las variables léxicas declaradas con
"my" están totalmente ocultos del mundo exterior, incluidas las subrutinas llamadas. Este es
Es cierto si es la misma subrutina llamada desde sí misma o desde otro lugar: cada llamada tiene su propia
dupdo.

Esto no significa que una variable "mi" declarada en un ámbito léxico que encierra estáticamente
sería invisible. Solo se cortan los ámbitos dinámicos. Por ejemplo, el "bumpx ()"
la función siguiente tiene acceso a la variable léxica $ x porque tanto el "mi" como el "sub"
ocurrió en el mismo ámbito, presumiblemente ámbito de archivo.

mi $ x = 10;
sub bumpx {$ x ++}

Sin embargo, un "eval ()" puede ver variables léxicas del ámbito en el que se está evaluando, por lo que
siempre que los nombres no estén ocultos por declaraciones dentro del propio "eval ()". Ver perlref.

La lista de parámetros para mi() se puede asignar a si lo desea, lo que le permite inicializar
sus variables. (Si no se proporciona un inicializador para una variable en particular, se crea con
el valor indefinido.) Comúnmente esto se usa para nombrar parámetros de entrada a una subrutina.
Ejemplos:

$ arg = "fred"; # "variable global
$ n = raíz cúbica(27);
print "$ arg piensa que la raíz es $ n \ n";
Fred piensa que la raíz es 3

raíz_cubo sub {
my $ arg = turno; # nombre no importa
$ arg ** = 1/3;
return $ arg;
}

El "mi" es simplemente un modificador en algo a lo que puede asignar. Entonces, cuando asignes a
variables en su lista de argumentos, "mi" no cambia si esas variables se ven como
un escalar o una matriz. Entonces

mi ($ foo) = ; # ¿INCORRECTO?
mi @FOO = ;

ambos proporcionan un contexto de lista en el lado derecho, mientras que

my $ foo = ;

proporciona un contexto escalar. Pero lo siguiente declara solo una variable:

my $ foo, $ bar = 1; # INCORRECTO

Eso tiene el mismo efecto que

my $ foo;
$ barra = 1;

La variable declarada no se introduce (no es visible) hasta después de la actual
declaración. Por lo tanto,

mi $ x = $ x;

se puede usar para inicializar un nuevo $ x con el valor del antiguo $ x, y la expresión

my $ x = 123 y $ x == 123

es falso a menos que el antiguo $ x tenga el valor 123.

Los alcances léxicos de las estructuras de control no están delimitados precisamente por las llaves que delimitan
sus bloques controlados; Las expresiones de control también forman parte de ese ámbito. Así en el
loops

while (my $ line = <>) {
$ línea = lc $ línea;
} Seguir {
imprimir $ línea;
}

el alcance de $ line se extiende desde su declaración hasta el resto de la construcción del bucle
(incluida la cláusula "continuar"), pero no más allá. Del mismo modo, en el condicional

si ((mi $ respuesta = ) = ~ / ^ sí $ / i) {
grados_usuario ();
} elsif ($ respuesta = ~ / ^ no $ / i) {
user_disagrees ();
} Else {
chomp $ respuesta;
die "'$ respuesta' no es ni 'sí' ni 'no'";
}

el alcance de $ answer se extiende desde su declaración hasta el resto de ese condicional,
incluidas las cláusulas "elsif" y "else", pero no más allá. Consulte "Declaraciones simples" en
perlsyn para obtener información sobre el alcance de las variables en declaraciones con modificadores.

El bucle "foreach" establece de forma predeterminada el alcance de su variable de índice de forma dinámica de la manera de
"local". Sin embargo, si la variable de índice tiene como prefijo la palabra clave "my", o si hay
ya un léxico con ese nombre en el alcance, entonces se crea un nuevo léxico en su lugar. Así en
el lazo

para mi $ i (1, 2, 3) {
alguna_función ();
}

el alcance de $ i se extiende hasta el final del ciclo, pero no más allá de él, representando el valor de
$ i inaccesible dentro de "alguna_función ()".

Algunos usuarios pueden desear fomentar el uso de variables de ámbito léxico. Como ayuda para
captura de usos implícitos para empaquetar variables, que siempre son globales, si dices

use 'vars' estrictas;

entonces cualquier variable mencionada desde allí hasta el final del bloque adjunto debe referirse
a una variable léxica, ser declarada previamente a través de "nuestro" o "use vars", o de lo contrario debe estar completamente
calificado con el nombre del paquete. De lo contrario, se producirá un error de compilación. Un bloque interior
puede contrarrestar esto con "no 'vars' estrictas".

Un "mi" tiene un efecto de tiempo de compilación y de tiempo de ejecución. En tiempo de compilación, el compilador toma
aviso de ello. La principal utilidad de esto es silenciar "usar 'vars' estrictas", pero es
también esencial para la generación de cierres como se detalla en perlref. Inicialización real
Sin embargo, se retrasa hasta el tiempo de ejecución, por lo que se ejecuta en el momento adecuado, como
cada vez a través de un bucle, por ejemplo.

Las variables declaradas con "my" no forman parte de ningún paquete y, por lo tanto, nunca están completamente
calificado con el nombre del paquete. En particular, no se le permite intentar hacer una
variable de paquete (u otro léxico global):

my $ paquete :: var; # ¡ERROR! Sintaxis ilegal

De hecho, una variable dinámica (también conocida como paquete o variables globales) todavía
accesible usando la notación "::" completamente calificada incluso mientras un léxico del mismo nombre
también es visible:

paquete principal;
local $ x = 10;
mi $ x = 20;
imprimir "$ x y $ :: x \ n";

Eso imprimirá 20 y 10.

Puede declarar "mis" variables en el ámbito más externo de un archivo para ocultar tales
identificadores del mundo exterior a ese archivo. Esto es similar en espíritu a la estática de C
variables cuando se utilizan a nivel de archivo. Para hacer esto con una subrutina se requiere
uso de un cierre (una función anónima que accede a los léxicos adjuntos). Si quieres
crear una subrutina privada que no se pueda llamar desde fuera de ese bloque, puede declarar
una variable léxica que contiene una sub referencia anónima:

my $ versión_secreta = '1.001-beta';
my $ secret_sub = sub {print $ secret_version};
& $ secret_sub ();

Siempre que la referencia nunca sea devuelta por ninguna función dentro del módulo, no fuera
El módulo puede ver la subrutina, porque su nombre no está en la tabla de símbolos de ningún paquete.
Recuerda que no es REALMENTE llamado $ algún_paquete :: versión_secreta o cualquier cosa; es solo
$ secret_version, no calificado y no calificado.

Sin embargo, esto no funciona con métodos de objeto; todos los métodos de objeto tienen que estar en el
tabla de símbolos de algún paquete que se encuentra. Consulte "Plantillas de funciones" en perlref para
algo así como una solución alternativa a esto.

Persistente Privado Variables
Hay dos formas de construir variables privadas persistentes en Perl 5.10. Primero, puedes
simplemente use la función "estado". O puede usar cierres, si desea seguir siendo compatible
con versiones anteriores a 5.10.

Persistente las variables vía estado()

A partir de Perl 5.10.0, puede declarar variables con la palabra clave "estado" en lugar de
"mi". Sin embargo, para que eso funcione, debe haber habilitado esa función de antemano, ya sea por
usando el pragma "característica", o usando "-E" en frases ingeniosas (ver característica). Empezando con
Perl 5.16, el formulario "CORE :: state" no requiere el pragma "feature".

La palabra clave "estado" crea una variable léxica (siguiendo las mismas reglas de alcance que "mi")
que persiste de una llamada de subrutina a la siguiente. Si una variable de estado reside dentro de una
subrutina anónima, entonces cada copia de la subrutina tiene su propia copia del estado
variable. Sin embargo, el valor de la variable de estado aún persistirá entre llamadas a
la misma copia de la subrutina anónima. (No olvide que "sub {...}" crea un nuevo
subrutina cada vez que se ejecuta).

Por ejemplo, el siguiente código mantiene un contador privado, que se incrementa cada vez que el
dame_otro () La función se llama:

use la función 'estado';
sub gimme_another {estado $ x; volver ++ $ x}

Y este ejemplo usa subrutinas anónimas para crear contadores separados:

use la función 'estado';
sub crear_contador {
return sub {estado $ x; volver ++ $ x}
}

Además, dado que $ x es léxico, ningún código Perl externo puede alcanzarlo ni modificarlo.

Cuando se combina con la declaración de variable, la asignación escalar simple a las variables de "estado" (como
en "estado $ x = 42") se ejecuta solo la primera vez. Cuando se evalúan tales declaraciones
veces posteriores, la asignación se ignora. El comportamiento de este tipo de asignación a
las variables no escalares no están definidas.

Persistente las variables con cierres

Solo porque una variable léxica tiene un alcance léxico (también llamado estáticamente) a su
incluir bloque, "eval" o "do" ARCHIVO, esto no significa que dentro de una función funcione
como una C estática. Normalmente funciona más como un C automático, pero con basura implícita
colección.

A diferencia de las variables locales en C o C ++, las variables léxicas de Perl no necesariamente obtienen
reciclado solo porque su alcance ha salido. Si algo mas permanente aun esta consciente
del léxico, se quedará. Siempre que algo más haga referencia a un léxico,
ese léxico no se liberará, que es como debería ser. No querrías que la memoria sea
libre hasta que termine de usarlo, o se mantenga cerca una vez que haya terminado. Basura automática
La colección se encarga de esto por ti.

Esto significa que puede devolver o guardar referencias a variables léxicas, mientras que para
devolver un puntero a un C automático es un error grave. También nos da una forma de simular C
función estática. Aquí hay un mecanismo para dar a una función variables privadas con ambos
alcance léxico y una vida estática. Si desea crear algo como la estática de C
variables, simplemente encierre la función completa en un bloque adicional y coloque la variable estática
fuera de la función pero en el bloque.

{
my $ valor_secreto = 0;
sub dame_otro {
return ++ $ valor_secreto;
}
}
# $ secret_val ahora se vuelve inalcanzable por el exterior
# world, pero conserva su valor entre llamadas a gimme_another

Si esta función se obtiene de un archivo independiente a través de "requerir" o "usar", entonces
probablemente esto esté bien. Si todo está en el programa principal, deberá hacer arreglos para
el "my" se ejecutará antes, ya sea colocando todo el bloque encima de su programa principal,
o más probablemente, colocando simplemente un bloque de código "BEGIN" a su alrededor para asegurarse de que se
ejecutado antes de que su programa comience a ejecutarse:

EMPEZAR {
my $ valor_secreto = 0;
sub dame_otro {
return ++ $ valor_secreto;
}
}

Consulte "BEGIN, UNITCHECK, CHECK, INIT y END" en perlmod sobre el código activado especial
bloques, "BEGIN", "UNITCHECK", "CHECK", "INIT" y "END".

Si se declara en el alcance más externo (el alcance del archivo), entonces los léxicos funcionan como los de C
estática del archivo. Están disponibles para todas las funciones en el mismo archivo declarado debajo de ellos,
pero son inaccesibles desde fuera de ese archivo. Esta estrategia a veces se usa en módulos
para crear variables privadas que todo el módulo pueda ver.

Temporalmente Valores vía local()
ADVERTENCIA: En general, debería utilizar "my" en lugar de "local", porque es más rápido y
más seguro. Las excepciones a esto incluyen las variables de puntuación global, identificadores de archivos globales
y formatos, y manipulación directa de la propia tabla de símbolos de Perl. "local" es principalmente
se utiliza cuando el valor actual de una variable debe ser visible para las subrutinas llamadas.

Sinopsis:

# localización de valores

local $ foo; # hacer $ foo dinámicamente local
local (@wid,% obtener); # hacer que la lista de variables sea local
local $ foo = "flurp"; # hacer que $ foo sea dinámico e iniciarlo
local @oof = @bar; # hacer que @oof sea dinámico e iniciarlo

local $ hash {clave} = "val"; # establece un valor local para esta entrada hash
eliminar $ hash {clave} local; # eliminar esta entrada para el bloque actual
local ($ cond? $ v1: $ v2); # varios tipos de soporte de lvalues
# localización

# localización de símbolos

local * FH; # localizar $ FH, @FH,% FH y FH ...
local * merlyn = * randal; # ahora $ merlyn es realmente $ randal, más
# @merlyn es realmente @randal, etc.
local * merlyn = 'randal'; # MISMA COSA: promover 'randal' a * randal
local * merlyn = \ $ randal; # solo alias $ merlyn, no @merlyn, etc.

Un "local" modifica sus variables enumeradas para que sean "locales" para el bloque adjunto, "eval" o
"do FILE" - y para cualquier subrutina , que son Desde within que bloquear. Un "local" simplemente da
valores temporales a variables globales (paquete de significado). Lo hace No crear un local
variable. Esto se conoce como alcance dinámico. El alcance léxico se realiza con "my", que
funciona más como las declaraciones automáticas de C.

Algunos tipos de lvalues ​​también se pueden localizar: elementos hash y de matriz y sectores,
condicionales (siempre que su resultado sea siempre localizable) y referencias simbólicas.
En cuanto a las variables simples, esto crea nuevos valores de ámbito dinámico.

Si se asigna más de una variable o expresión a "local", deben colocarse en
paréntesis. Este operador funciona guardando los valores actuales de esas variables en su
lista de argumentos en una pila oculta y restaurarlos al salir del bloque, subrutina o
eval. Esto significa que las subrutinas llamadas también pueden hacer referencia a la variable local, pero no
el global. La lista de argumentos puede asignarse si lo desea, lo que le permite
inicialice sus variables locales. (Si no se proporciona un inicializador para una variable en particular,
se crea con un valor indefinido).

Debido a que "local" es un operador en tiempo de ejecución, se ejecuta cada vez a través de un bucle.
En consecuencia, es más eficiente localizar sus variables fuera del ciclo.

Gramático nota on local()

Un "local" es simplemente un modificador en una expresión lvalue. Cuando asigna a un "local" izado
variable, el "local" no cambia si su lista se ve como un escalar o una matriz.
So

local ($ foo) = ;
local @FOO = ;

ambos proporcionan un contexto de lista en el lado derecho, mientras que

local $ foo = ;

proporciona un contexto escalar.

aplicaciones móviles of especial las variables

Si localiza una variable especial, le dará un nuevo valor, pero su magia
no se irá. Eso significa que todos los efectos secundarios relacionados con esta magia aún funcionan con el
valor localizado.

Esta característica permite que un código como este funcione:

# Leer todo el contenido de FILE en $ slurp
{local $ / = indef; $ sorber = ; }

Sin embargo, tenga en cuenta que esto restringe la localización de algunos valores; por ejemplo, el
la siguiente declaración muere, a partir de perl 5.10.0, con un error Modificación of a sólo lectura
valor atentado, porque la variable $ 1 es mágica y de solo lectura:

local $ 1 = 2;

Una excepción es la variable escalar predeterminada: a partir de perl 5.14 "local ($ _)"
siempre quite toda la magia de $ _, para que sea posible reutilizar de forma segura $ _ en una subrutina.

ADVERTENCIA: La localización de matrices vinculadas y hashes no funciona actualmente como se describe.
Esto se solucionará en una versión futura de Perl; Mientras tanto, evite el código que se basa en
cualquier comportamiento particular de localizar matrices vinculadas o hashes (localizar
elementos todavía está bien). Consulte "La localización de matrices vinculadas y hashes está rota" en perl58delta
para obtener más información.

aplicaciones móviles of globos

El constructo

nombre local;

crea una entrada de tabla de símbolos completamente nueva para el "nombre" global en el paquete actual. Ese
significa que todas las variables en su espacio global ($ nombre, @nombre,% nombre, & nombre y el "nombre"
filehandle) se restablecen dinámicamente.

Esto implica, entre otras cosas, que cualquier magia eventualmente llevada por esas variables es
localmente perdido. En otras palabras, decir "local * /" no tendrá ningún efecto en el
valor del separador de registros de entrada.

aplicaciones móviles of elementos of compuesto tipos

También vale la pena tomarse un momento para explicar qué sucede cuando "localiza" a un miembro de un
tipo compuesto (es decir, una matriz o elemento hash). En este caso, el elemento es "local" izado
by nombre . Esto significa que cuando finaliza el alcance de "local ()", el valor guardado será
restaurado al elemento hash cuya clave se nombró en el "local ()", o el elemento de matriz
cuyo índice fue nombrado en el "local ()". Si ese elemento se eliminó mientras el "local ()"
estaba en efecto (por ejemplo, mediante un "delete ()" de un hash o un "shift ()" de una matriz),
volver a existir, posiblemente extendiendo una matriz y completando el
elementos con "undef". Por ejemplo, si dices

% hash = ('Esto' => 'es', 'a' => 'prueba');
@ary = (0..5);
{
local ($ ary [5]) = 6;
local ($ hash {'a'}) = 'perforar';
while (my $ e = pop (@ary)) {
imprimir "$ e... \ n";
último a menos que $ e> 3;
}
si (@ary) {
$ hash {'solo una'} = 'prueba';
eliminar $ hash {'a'};
}
}
print join ('', map {"$ _ $ hash {$ _}"} ordenar claves% hash), ". \ n";
imprimir "La matriz tiene", escalar (@ary), "elementos:",
join (',', map {definido $ _? $ _: 'undef'} @ary), "\ n";

Perl imprimirá

6. . .
4. . .
3. . .
Esta es una prueba solo una prueba.
La matriz tiene 6 elementos: 0, 1, 2, undef, undef, 5

El comportamiento de local() en miembros inexistentes de tipos compuestos está sujeto a cambios en
futuro.

Localizada eliminación of elementos of compuesto tipos

Puede utilizar las construcciones "eliminar $ local $ array [$ idx]" y "eliminar local $ hash {key}" para
eliminar una entrada de tipo compuesto para el bloque actual y restaurarla cuando finalice. Ellos
devuelve el valor de matriz / hash antes de la localización, lo que significa que son
respectivamente equivalente a

hacer {
my $ val = $ matriz [$ idx];
local $ matriz [$ idx];
eliminar $ matriz [$ idx];
$ val
}

y

hacer {
my $ val = $ hash {clave};
local $ hash {clave};
eliminar $ hash {clave};
$ val
}

excepto que para aquellos, el "local" tiene como alcance el bloque "do". También se aceptan rodajas.

mi% hash = (
a => [7, 8, 9],
b => 1,
)

{
my $ a = eliminar $ hash {a} local;
# $ a es [7, 8, 9]
#% hash es (b => 1)

{
my @nums = eliminar local @ $ a [0, 2]
# @nums es (7, 9)
# $ a es [undef, 8]

$ a [0] = 999; # se borrará cuando finalice el alcance
}
# $ a ha vuelto a [7, 8, 9]

}
#% hash ha vuelto a su estado original

valor L subrutinas
Es posible devolver un valor modificable de una subrutina. Para hacer esto, tienes que
declare la subrutina para devolver un lvalue.

my $ val;
sub canmod: lvalue {
$ val; # o: return $ val;
}
sub nomod {
$ val;
}

canmod () = 5; # asigna a $ val
nomod () = 5; # ERROR

El contexto escalar / de lista para la subrutina y para el lado derecho de la asignación es
determinado como si la llamada a la subrutina fuera reemplazada por un escalar. Por ejemplo, considere:

datos (2,3) = obtener_datos (3,4);

Ambas subrutinas aquí se llaman en un contexto escalar, mientras que en:

(datos (2,3)) = obtener_datos (3,4);

y en:

(datos(2)datos(3)) = obtener_datos (3,4);

todas las subrutinas se llaman en un contexto de lista.

Las subrutinas Lvalue son convenientes, pero debe tener en cuenta que, cuando se usan con
objetos, pueden violar la encapsulación. Un mutador normal puede verificar el argumento proporcionado
antes de establecer el atributo que está protegiendo, una subrutina lvalue no puede. Si tu
requieren cualquier procesamiento especial al almacenar y recuperar los valores, considere usar el
Módulo CPAN Sentinel o algo similar.

Léxico Subrutinas
ADVERTENCIA: Las subrutinas léxicas aún son experimentales. La función puede modificarse o
eliminado en futuras versiones de Perl.

Las subrutinas léxicas solo están disponibles en el pragma "use feature 'lexical_subs'",
que produce una advertencia a menos que la categoría de advertencias "experimental :: lexical_subs" sea
discapacitado.

A partir de Perl 5.18, puede declarar una subrutina privada con "mi" o "estado". Como
con variables de estado, la palabra clave "estado" solo está disponible en "usar función 'estado'" o
"use 5.010" o superior.

Estas subrutinas solo son visibles dentro del bloque en el que están declaradas, y solo
después de esa declaración:

sin advertencias "experimental :: lexical_subs";
use la función 'lexical_subs';

foo (); # llama al paquete / subrutina global
estado sub foo {
foo (); # también llama a la subrutina del paquete
}
foo (); # llamadas sub "estado"
my $ ref = \ & foo; # tomar una referencia al sub "estado"

mi barra secundaria {...}
bar(); # llama "mi" sub

Para usar una subrutina léxica desde dentro de la subrutina misma, debe declararla previamente.
La sintaxis de definición de subrutina "sub foo {...}" respeta cualquier "my sub" anterior; o "estado
sub; "declaración.

mi sub baz; # predeclaración
sub baz {# define el sub "mi"
baz (); # llamada recursiva
}

"estado sub" vs "mi sub"

¿Cuál es la diferencia entre subs "estatales" y "mis" subs? Cada vez que esa ejecución
entra en un bloque cuando se declaran "mis" subs, se crea una nueva copia de cada sub. "Estado"
las subrutinas persisten desde una ejecución del bloque contenedor hasta la siguiente.

Entonces, en general, las subrutinas de "estado" son más rápidas. Pero "mis" subs son necesarios si quieres
para crear cierres:

sin advertencias "experimental :: lexical_subs";
use la función 'lexical_subs';

sub lo que sea {
my $ x = turno;
mi sub interior {
... haz algo con $ x ...
}
interno();
}

En este ejemplo, se crea un nuevo $ x cuando se llama "lo que sea", y también un nuevo "interno",
que puede ver el nuevo $ x. Un sub "estado" solo verá el $ x de la primera llamada a
"lo que".

"nuestro" subrutinas

Como "nuestra $ variable", "nuestro sub" crea un alias léxico para la subrutina del paquete del
mismo nombre.

Los dos usos principales para esto son volver a usar el paquete sub dentro de un interior
alcance:

sin advertencias "experimental :: lexical_subs";
use la función 'lexical_subs';

sub foo {...}

barra secundaria {
mi sub foo {...}
{
# necesito usar el foo externo aquí
nuestro sub foo;
foo ();
}
}

y hacer una subrutina visible para otros paquetes en el mismo alcance:

paquete MySneakyModule;

sin advertencias "experimental :: lexical_subs";
use la función 'lexical_subs';

nuestro sub do_something {...}

sub hacer_algo_con_llamador {
paquete DB;
() = llamante 1; # establece @DB :: args
hacer_algo (@args); # usa MySneakyModule :: do_something
}

Pasando (Paso) Símbolo Tabla Entries (globos de tipo)
ADVERTENCIA: El mecanismo descrito en esta sección era originalmente la única forma de simular
pasar por referencia en versiones anteriores de Perl. Si bien todavía funciona bien en la moderna
versiones, el nuevo mecanismo de referencia es generalmente más fácil de trabajar. Vea abajo.

A veces, no desea pasar el valor de una matriz a una subrutina, sino más bien el nombre
de la misma, de modo que la subrutina pueda modificar la copia global de la misma en lugar de trabajar con una
copia local. En perl, puede hacer referencia a todos los objetos de un nombre en particular colocando el prefijo
nombre con una estrella: * foo. Esto a menudo se conoce como "typeglob", porque la estrella en el
El frente puede considerarse como una coincidencia de comodines para todos los caracteres de prefijo divertidos en
variables y subrutinas y tal.

Cuando se evalúa, el typeglob produce un valor escalar que representa todos los objetos de
ese nombre, incluido cualquier identificador de archivo, formato o subrutina. Cuando se asigna a, causa
el nombre mencionado para hacer referencia a cualquier valor "*" que se le haya asignado. Ejemplo:

sub doble {
local (* someary) = @_;
foreach $ elem (@someary) {
$ elem * = 2;
}
}
doubleary (* foo);
doubleary (* barra);

Los escalares ya se pasan por referencia, por lo que puede modificar los argumentos escalares sin usar
este mecanismo haciendo referencia explícita a $ _ [0] etc. Puede modificar todos los elementos de
una matriz pasando todos los elementos como escalares, pero tienes que usar el mecanismo "*" (o
el mecanismo de referencia equivalente) para "empujar", "sacar" o cambiar el tamaño de una matriz. Eso
Sin duda será más rápido pasar el typeglob (o referencia).

Incluso si no desea modificar una matriz, este mecanismo es útil para pasar múltiples
matrices en una sola LISTA, porque normalmente el mecanismo LIST fusionará toda la matriz
valores para que no pueda extraer las matrices individuales. Para obtener más información sobre typeglobs, consulte
"Typeglobs y Filehandles" en perldata.

¿Cuándo? a Sin embargo Utilice local()
A pesar de la existencia de "my", todavía hay tres lugares donde el operador "local"
todavía brilla. De hecho, en estos tres lugares, deben utilice "local" en lugar de "mi".

1. Necesita darle a una variable global un valor temporal, especialmente $ _.

Las variables globales, como @ARGV o las variables de puntuación, deben ser "locales" izadas
con "local ()". Este bloque se lee en / etc / motdy lo divide en trozos separados
por líneas de signos iguales, que se colocan en @Fields.

{
local @ARGV = ("/ etc / motd");
local $ / = undef;
local $ _ = <>;
@Campos = dividir / ^ \ s * = + \ s * $ /;
}

En particular, es importante "localizar" ize $ _ en cualquier rutina que se le asigne.
Busque asignaciones implícitas en condicionales "while".

2. Necesita crear un archivo local o un identificador de directorio o una función local.

Una función que necesita un identificador de archivo propio debe usar "local ()" en un
typeglob. Esto se puede utilizar para crear nuevas entradas en la tabla de símbolos:

sub cola {
local (* LECTOR, * ESCRITOR); # ¡no es mio!
pipe (READER, WRITER) o morir "pipe: $!";
return (* LECTOR, * ESCRITOR);
}
($ cabeza, $ cola) = ioqueue ();

Consulte el módulo Símbolo para conocer una forma de crear entradas anónimas en la tabla de símbolos.

Debido a que la asignación de una referencia a un typeglob crea un alias, esto se puede usar para
crear lo que es efectivamente una función local, o al menos, un alias local.

{
local * crecer = \ & encoger; # solo hasta que este bloque salga
crecer(); # realmente llama a shrink ()
moverse(); # si move () crece () s, también encoge () s
}
crecer(); # obtener el crecimiento real () de nuevo

Consulte "Plantillas de funciones" en perlref para obtener más información sobre cómo manipular funciones por nombre en
de esta manera.

3. Desea cambiar temporalmente solo un elemento de una matriz o hash.

Puede "localizar" sólo un elemento de un agregado. Por lo general, esto se hace en
dinámica:

{
local $ SIG {INT} = 'IGNORAR';
funct (); # ininterrumpible
}
# interrumpibilidad restaurada automáticamente aquí

Pero también funciona con agregados declarados léxicamente.

Pass by Referencias
Si desea pasar más de una matriz o hash a una función, o devolverlos desde
y hacer que mantengan su integridad, entonces tendrás que usar una
pasar por referencia. Antes de hacer eso, debe comprender las referencias como se detalla en
perlref. De lo contrario, es posible que esta sección no tenga mucho sentido para usted.

A continuación se muestran algunos ejemplos sencillos. Primero, pasemos varias matrices a una función y
haz que "salte" todo el tiempo, devolviendo una nueva lista de todos sus últimos elementos anteriores:

@tailings = popmany (\ @a, \ @b, \ @c, \ @d);

sub popmany {
my $ aref;
mi @retlist = ();
foreach $ aref (@_) {
empujar @retlist, pop @ $ aref;
}
devolver @retlist;
}

Así es como puede escribir una función que devuelva una lista de claves que ocurren en todos los
hashes pasados ​​a él:

@common = inter (\% foo, \% bar, \% joe);
sub entre {
my ($ k, $ href,% visto); # lugareños
foreach $ href (@_) {
while ($ k = cada% $ href) {
$ visto {$ k} ++;
}
}
devuelve grep {$ visto {$ _} == @_} claves% visto;
}

Hasta ahora, estamos usando solo el mecanismo normal de devolución de lista. Que pasa si quieres
pasar o devolver un hash? Bueno, si está usando solo uno de ellos, o no le importan
concatenando, entonces la convención de llamada normal está bien, aunque un poco cara.

Donde la gente se mete en problemas es aquí:

(@a, @b) = func (@c, @d);
or
(% a,% b) = func (% c,% d);

Esa sintaxis simplemente no funcionará. Establece solo @a o% ay borra @b o% b. Más el
la función no se pasó a dos matrices o hashes separados: obtuvo una lista larga en @_,
como siempre.

Si puede hacer arreglos para que todos se ocupen de esto a través de referencias, es un código más limpio,
aunque no es tan agradable a la vista. Aquí hay una función que toma dos referencias de matriz como
argumentos, devolviendo los dos elementos de la matriz en orden de cuántos elementos tienen en
ellos:

($ aref, $ bref) = func (\ @ c, \ @d);
print "@ $ aref tiene más de @ $ bref \ n";
función secundaria {
mi ($ cref, $ dref) = @_;
si (@ $ cref> @ $ dref) {
return ($ cref, $ dref);
} Else {
return ($ dref, $ cref);
}
}

Resulta que en realidad también puedes hacer esto:

(* a, * b) = func (\ @ c, \ @d);
print "@a tiene más de @b \ n";
función secundaria {
local (* c, * d) = @_;
si (@c> @d) {
return (\ @c, \ @d);
} Else {
return (\ @d, \ @c);
}
}

Aquí estamos usando typeglobs para hacer alias de tablas de símbolos. Sin embargo, es un poco sutil
y tampoco funcionará si usa "mis" variables, porque solo las globales (incluso disfrazadas
como "local" s) están en la tabla de símbolos.

Si está pasando identificadores de archivos, generalmente podría usar el typeglob desnudo, como
* STDOUT, pero las referencias de typeglobs también funcionan. Por ejemplo:

balbucear (\ * STDOUT);
sub balbuceo {
my $ fh = turno;
print $ fh "her um bueno a hmmm \ n";
}

$ rec = get_rec (\ * STDIN);
sub get_rec {
my $ fh = turno;
return escalar <$ fh>;
}

Si planea generar nuevos identificadores de archivos, puede hacer esto. Aviso para devolver
solo el * FH desnudo, no su referencia.

abrir sub {
my $ path = shift;
local * FH;
volver abierto (FH, $ ruta)? * FH: indefinido;
}

prototipos
Perl admite un tipo muy limitado de verificación de argumentos en tiempo de compilación mediante la función
prototipos. Esto se puede declarar en la sección PROTO o con un prototipo
atributo. Si declara cualquiera de

sub mypush (+ @)
sub mypush: prototipo (+ @)

entonces "mypush ()" toma argumentos exactamente como lo hace "push ()".

Si las firmas de subrutinas están habilitadas (consulte "Firmas"), entonces la sintaxis PROTO más corta es
no disponible, porque chocaría con las firmas. En ese caso, un prototipo solo puede
declararse en forma de atributo.

La declaración de función debe estar visible en tiempo de compilación. El prototipo afecta solo
interpretación de llamadas de nuevo estilo a la función, donde nuevo estilo se define como no usar
el personaje. En otras palabras, si lo llama como una función incorporada, entonces
se comporta como una función incorporada. Si lo llama como una subrutina pasada de moda, entonces
se comporta como una subrutina pasada de moda. Naturalmente, se cae de esta regla que
los prototipos no influyen en las referencias de subrutinas como "\ & foo" o en las
llamadas a subrutinas como "& {$ subref}" o "$ subref -> ()".

Las llamadas a métodos tampoco están influenciadas por los prototipos, porque la función a llamar es
indeterminado en tiempo de compilación, ya que el código exacto llamado depende de la herencia.

Debido a que la intención de esta función es principalmente permitirle definir subrutinas que funcionen
como funciones integradas, aquí hay prototipos para algunas otras funciones que analizan casi
exactamente como el incorporado correspondiente.

Declarado como llamado

sub mylink ($$) mylink $ antiguo, $ nuevo
sub myvec ($$$) myvec $ var, $ compensación, 1
sub myindex ($$; $) myindex & getstring, "substr"
sub mysyswrite ($$$; $) mysyswrite $ buf, 0, longitud ($ buf) - $ off, $ off
sub myreverse (@) myreverse $ a, $ b, $ c
sub myjoin ($ @) myjoin ":", $ a, $ b, $ c
sub mipop (+) mipop @array
sub mysplice (+ $$ @) mysplice @array, 0, 2, @pushme
sub mykeys (+) mykeys% {$ hashref}
sub myopen (*; $) myopen HANDLE, $ nombre
sub mypipe (**) mypipe INDICADOR DE LECTURA, INDICADOR DE ESCRITURA
sub mygrep (& @) mygrep {/ foo /} $ a, $ b, $ c
sub myrand (; $) myrand 42
sub mitiempo () mitiempo

Cualquier carácter prototipo con barra invertida representa un argumento real que debe comenzar con
ese carácter (opcionalmente precedido por "mi", "nuestro" o "local"), con la excepción de "$",
que aceptará cualquier expresión escalar lvalue, como "$ foo = 7" o
"mi_función () -> [0]". El valor pasado como parte de @_ será una referencia al valor real
argumento dado en la llamada a la subrutina, obtenido aplicando "\" a ese argumento.

Puede utilizar la notación de grupo de barra invertida "\ []" para especificar más de un argumento permitido
tipo. Por ejemplo:

sub myref (\ [$ @% & *])

permitirá llamar myref () as

myref $ var
miref @array
myref% hash
myref & sub
myref * glob

y el primer argumento de myref () será una referencia a un escalar, una matriz, un hash, un
código, o un glob.

Los prototipos de personajes sin barra invertida tienen significados especiales. Cualquier "@" o "%" sin barra invertida
se come todos los argumentos restantes y fuerza el contexto de la lista. Un argumento representado por "$"
fuerza el contexto escalar. Un "&" requiere una subrutina anónima, que, si se pasa como
primer argumento, no requiere la palabra clave "sub" o una coma posterior.

Un "*" permite que la subrutina acepte una expresión simple, constante, escalar, typeglob,
o una referencia a un typeglob en ese espacio. El valor estará disponible para la subrutina.
ya sea como un escalar simple, o (en los dos últimos casos) como una referencia al typeglob.
Si desea convertir siempre dichos argumentos en una referencia de typeglob, utilice
Símbolo :: qualify_to_ref () como sigue:

use el símbolo 'qualify_to_ref';

sub foo (*) {
my $ fh = qualify_to_ref (turno, llamador);
...
}

El prototipo "+" es una alternativa especial a "$" que actuará como "\ [@%]" cuando se le dé un
matriz literal o variable hash, pero de lo contrario forzará un contexto escalar en el argumento.
Esto es útil para funciones que deberían aceptar una matriz literal o una matriz.
referencia como argumento:

sub mypush (+ @) {
my $ aref = shift;
die "No es una matriz o una referencia de matriz" a menos que ref $ aref eq 'ARRAY';
empujar @ $ aref, @_;
}

Al usar el prototipo "+", su función debe verificar que el argumento sea de un
tipo aceptable.

Un punto y coma (";") separa los argumentos obligatorios de los opcionales. Es redundante
antes de "@" o "%", que devoran todo lo demás.

Como último carácter de un prototipo, o justo antes de un punto y coma, una "@" o un "%", puede
use "_" en lugar de "$": si no se proporciona este argumento, se usará $ _ en su lugar.

Observe cómo los últimos tres ejemplos de la tabla anterior son tratados especialmente por el analizador.
"mygrep ()" se analiza como un verdadero operador de lista, "myrand ()" se analiza como un verdadero unario
operador con precedencia unaria lo mismo que "rand ()", y "mytime ()" es realmente sin
argumentos, como "time ()". Es decir, si dices

mi tiempo +2;

obtendrás "mytime () + 2", no mi tiempo(2), que es como se analizaría sin un
prototipo. Si desea forzar que una función unaria tenga la misma precedencia que una lista
operador, agregue ";" hasta el final del prototipo:

sub mygetprotobynumber ($;);
mygetprotobynumber $ a> $ b; # analizado como mygetprotobynumber ($ a> $ b)

Lo interesante de "&" es que puede generar una nueva sintaxis con él, siempre que sea
en la posición inicial:

sub intento (& @) {
my ($ intento, $ captura) = @_;
eval {& $ try};
si ($ @) {
local $ _ = $ @;
& $ catch;
}
}
captura secundaria (&) {$ _ [0]}

tratar {
morir "phooey";
} captura {
/ phooey / e imprime "unhooey \ n";
};

Eso imprime "imputo". (Sí, todavía hay problemas sin resolver relacionados con
visibilidad de @_. Estoy ignorando esa pregunta por el momento. (Pero tenga en cuenta que si hacemos
@_ con alcance léxico, esas subrutinas anónimas pueden actuar como cierres ...
suena un poco Lispish? (No importa.))))

Y aquí hay una reimplementación del operador "grep" de Perl:

sub mygrep (& @) {
mi $ código = turno;
mi @resultado;
foreach $ _ (@_) {
empujar (@result, $ _) si & $ code;
}
@resultado;
}

Algunas personas preferirían prototipos alfanuméricos completos. Los alfanuméricos han sido
dejado intencionalmente fuera de los prototipos con el propósito expreso de algún día en el futuro
agregar parámetros formales con nombre. El objetivo principal del mecanismo actual es permitir que el módulo
los escritores proporcionan mejores diagnósticos para los usuarios del módulo. Larry siente la notación bastante
comprensible para los programadores de Perl, y que no se inmiscuirá mucho en la carne de
el módulo, ni dificultar su lectura. El ruido de la línea se encapsula visualmente en un
pastilla pequeña que es fácil de tragar.

Si intenta utilizar una secuencia alfanumérica en un prototipo, generará una
advertencia - "Carácter ilegal en prototipo ...". Desafortunadamente, las versiones anteriores de Perl
permitió que se utilizara el prototipo siempre que su prefijo fuera un prototipo válido. La advertencia
puede actualizarse a un error fatal en una versión futura de Perl una vez que la mayoría de
el código infractor es fijo.

Probablemente sea mejor crear un prototipo de nuevas funciones, no adaptar el prototipo a otras más antiguas.
Eso es porque debe tener especial cuidado con las imposiciones silenciosas de diferentes listas
versus contextos escalares. Por ejemplo, si decide que una función debe tomar solo una
parámetro, como este:

función secundaria ($) {
my $ n = turno;
imprimir "me diste $ n \ n";
}

y alguien lo ha estado llamando con una matriz o expresión que devuelve una lista:

func (@foo);
func (dividir /: /);

Luego, acaba de proporcionar un "escalar" automático delante de su argumento, que puede ser
más que sorprendente. El viejo @foo que solía sostener una cosa no se pasa
in. En cambio, "func ()" ahora se pasa en un 1; es decir, el número de elementos en @foo.
Y la "división" se llama en contexto escalar para que comience a garabatear en su parámetro @_
lista. ¡Ay!

Si un sub tiene tanto un PROTO como un BLOQUE, el prototipo no se aplica hasta después del BLOQUE
está completamente definido. Esto significa que una función recursiva con un prototipo debe ser
predeclarado para que el prototipo surta efecto, así:

sub foo ($$);
sub foo ($$) {
foo 1, 2;
}

Todo esto es muy poderoso, por supuesto, y debe usarse solo con moderación para hacer que el
mundo un lugar mejor.

Constante Funciones
Las funciones con un prototipo de "()" son candidatos potenciales para la inserción. Si el resultado
después de la optimización y el plegado constante es un escalar constante o de ámbito léxico
que no tiene otras referencias, entonces se utilizará en lugar de las llamadas a funciones realizadas
sin "&". Las llamadas realizadas con "&" nunca se incluyen en línea. (Ver constante.pm para una manera fácil de
declarar la mayoría de las constantes.)

Las siguientes funciones estarán todas en línea:

sub pi () {3.14159} # No es exacto, pero cercano.
sub PI () {4 * atan2 1, 1} # Tan bueno como parece,
# ¡y también está en línea!
sub ST_DEV () {0}
sub ST_INO () {1}

sub FLAG_FOO () {1 << 8}
sub FLAG_BAR () {1 << 9}
sub FLAG_MASK () {FLAG_FOO | FLAG_BAR}

sub OPT_BAZ () {no (0x1B58 y FLAG_MASK)}

sub N () {int (OPT_BAZ) / 3}

sub FOO_SET () {1 si FLAG_MASK & FLAG_FOO}
sub FOO_SET2 () {si (FLAG_MASK & FLAG_FOO) {1}}

(Tenga en cuenta que el último ejemplo no siempre estaba incluido en Perl 5.20 y versiones anteriores, lo que
no se comportan de forma coherente con las subrutinas que contienen ámbitos internos).
inlining mediante el uso de un "retorno" explícito:

subbaz_val() {
si (OPT_BAZ) {
23 regresar;
}
else {
42 regresar;
}
}
sub bonk_val () {return 12345}

Como se mencionó anteriormente, también puede declarar subs inline dinámicamente en el momento de BEGIN si su
body consta de un escalar de ámbito léxico que no tiene otras referencias. Solo el primero
El ejemplo aquí estará en línea:

EMPEZAR {
my $ var = 1;
no hay "referencias" estrictas;
* INLINED = sub () {$ var};
}

EMPEZAR {
my $ var = 1;
my $ ref = \ $ var;
no hay "referencias" estrictas;
* NOT_INLINED = sub () {$ var};
}

Una advertencia no tan obvia con esto (ver [RT # 79908]) es que la variable será
inmediatamente en línea, y dejará de comportarse como una variable léxica normal, por ejemplo, esto
imprimir 79907, no 79908:

EMPEZAR {
mi $ x = 79907;
* RT_79908 = sub () {$ x};
$ x ++;
}
imprimir RT_79908 (); # impresiones 79907

A partir de Perl 5.22, este comportamiento defectuoso, aunque se conserva para compatibilidad con versiones anteriores, es
detectado y emite una advertencia de obsolescencia. Si desea que la subrutina esté en línea (con
sin advertencia), asegúrese de que la variable no se utilice en un contexto en el que pueda modificarse
aparte de donde se declara.

# Bien, sin advertencia
EMPEZAR {
mi $ x = 54321;
* INLINED = sub () {$ x};
}
# Advierte. Las versiones futuras de Perl dejarán de incluirlo.
EMPEZAR {
my $ x;
$ x = 54321;
* ALSO_INLINED = sub () {$ x};
}

Perl 5.22 también introduce el atributo experimental "const" como alternativa. (Desactivar
las advertencias "experimental :: const_attr" si desea utilizarlo). Cuando se aplica a un
subrutina anónima, obliga a que se llame al sub cuando la expresión "sub" es
evaluado. El valor de retorno se captura y se convierte en una subrutina constante:

mi $ x = 54321;
* INLINED = sub: const {$ x};
$ x ++;

El valor de retorno de "INLINED" en este ejemplo siempre será 54321, independientemente de si es posterior
modificaciones a $ x. También puede poner cualquier código arbitrario dentro del sub, como será
ejecutado inmediatamente y su valor de retorno capturado de la misma manera.

Si realmente desea una subrutina con un prototipo "()" que devuelva una variable léxica,
puede forzarlo a que no se incluya en la línea agregando un "retorno" explícito:

EMPEZAR {
mi $ x = 79907;
* RT_79908 = sub () {return $ x};
$ x ++;
}
imprimir RT_79908 (); # impresiones 79908

La forma más fácil de saber si una subrutina estaba insertada es usando B :: Deparse. Considera esto
ejemplo de dos subrutinas que devuelven 1, una con un prototipo "()" que hace que sea
en línea y uno sin (con salida deparse truncada para mayor claridad):

$ perl -MO = Deparse -le 'sub ONE {1} if (ONE) {print ONE if ONE}'
sub UNO {
1;
}
si uno ) {
imprimir UNO () si es UNO;
}
$ perl -MO = Deparse -le 'sub ONE () {1} if (ONE) {print ONE if ONE}'
sub ONE () {1}
hacer {
print 1
};

Si redefine una subrutina que era elegible para la inserción, recibirá una advertencia de
defecto. Puede utilizar esta advertencia para saber si una subrutina en particular está
se considera insertable, ya que es diferente a la advertencia para anular las líneas no insertadas
subrutinas:

$ perl -e 'sub uno () {1} sub uno () {2}'
Subrutina constante uno redefinida en -e línea 1.
$ perl -we 'sub uno {1} sub uno {2}'
Subrutina uno redefinida en -e línea 1.

La advertencia se considera lo suficientemente grave como para no verse afectada por -w interruptor (o su
ausencia) porque las invocaciones compiladas previamente de la función seguirán utilizando la
antiguo valor de la función. Si necesita poder redefinir la subrutina, necesita
asegúrese de que no esté en línea, ya sea soltando el prototipo "()" (que cambia la llamada
semántica, así que ten cuidado) o frustrando el mecanismo de alineación de alguna otra manera, por ejemplo,
agregando un "retorno" explícito, como se mencionó anteriormente:

sub not_inline () {return 23}

Primordial Incorporado Funciones
Es posible que se anulen muchas funciones integradas, aunque esto solo se debe intentar de vez en cuando
y por una buena razón. Normalmente, esto puede realizarse mediante un paquete que intenta emular
Falta la funcionalidad incorporada en un sistema que no es Unix.

La anulación se puede hacer solo importando el nombre de un módulo en tiempo de compilación - ordinario
la predeclaración no es lo suficientemente buena. Sin embargo, el pragma "use subs" le permite, de hecho,
predeclare subs a través de la sintaxis de importación, y estos nombres pueden anular los incorporados:

use subs 'chdir', 'chroot', 'chmod', 'chown';
chdir $ en alguna parte;
sub chdir {...}

Para hacer referencia inequívoca al formulario integrado, anteponga el nombre integrado con el especial
calificador de paquete "CORE ::". Por ejemplo, decir "CORE :: open ()" siempre se refiere al
incorporado "open ()", incluso si el paquete actual ha importado alguna otra subrutina llamada
"& open ()" desde otro lugar. Aunque parece una llamada de función normal, no lo es:
el prefijo CORE :: en ese caso es parte de la sintaxis de Perl, y funciona para cualquier palabra clave,
independientemente de lo que haya en el paquete CORE. Tomando una referencia a él, es decir,
"\ & CORE :: open", solo funciona para algunas palabras clave. Ver CORE.

Los módulos de la biblioteca no deberían, en general, exportar nombres integrados como "open" o "chdir" como parte
de su lista @EXPORT predeterminada, porque estos pueden colarse en el espacio de nombres de otra persona y
cambiar la semántica inesperadamente. En cambio, si el módulo agrega ese nombre a @EXPORT_OK,
entonces es posible que un usuario importe el nombre explícitamente, pero no implícitamente. Es decir,
ellos podrían decir

use el Módulo 'abierto';

e importaría la anulación "abierta". Pero si dijeron

módulo de uso;

obtendrían las importaciones predeterminadas sin anulaciones.

El mecanismo anterior para anular lo incorporado se restringe, de manera bastante deliberada, a la
paquete que solicita la importación. Hay un segundo método que a veces es aplicable
cuando desee anular un elemento integrado en todas partes, sin tener en cuenta los límites del espacio de nombres.
Esto se logra importando un sub en el espacio de nombres especial "CORE :: GLOBAL ::". Aquí está
un ejemplo que reemplaza descaradamente al operador "glob" con algo que
comprende expresiones regulares.

paquete REGlob;
requiera exportador;
@ISA = 'Exportador';
@EXPORT_OK = 'glob';

subimportación {
mi $ pkg = turno;
volver a menos que @_;
my $ sym = shift;
my $ donde = ($ sym = ~ s / ^ GLOBAL _ //? 'CORE :: GLOBAL': llamador(0));
$ paquete-> exportar ($ donde, $ sym, @_);
}

globo secundario {
my $ pat = turno;
mi @got;
if (opendir my $ d, '.') {
@got = grep / $ pat /, readdir $ d;
closedir $ d;
}
volver @got;
}
1;

Y así es como podría usarse (ab):

#use REGlob 'GLOBAL_glob'; # anular glob () en TODOS los espacios de nombres
paquete Foo;
use REGlob 'glob'; # anular glob () en Foo :: solo
imprimir para <^ [a-z _] + \. pm \ $>; # mostrar todos los módulos pragmáticos

El comentario inicial muestra un ejemplo artificial e incluso peligroso. Anulando "glob"
globalmente, estarías forzando el comportamiento nuevo (y subversivo) para el operador "glob"
para cada espacio de nombres, sin el conocimiento completo o la cooperación de los módulos que
poseer esos espacios de nombres. Naturalmente, esto debe hacerse con extrema precaución, si es necesario
hecho en absoluto.

El ejemplo "REGlob" anterior no implementa todo el soporte necesario para anular limpiamente
el operador "glob" de perl. El "glob" incorporado tiene diferentes comportamientos dependiendo de si
aparece en un contexto escalar o de lista, pero nuestro "REGlob" no. De hecho, muchas perl
incorporados tienen tales comportamientos sensibles al contexto, y estos deben ser apoyados adecuadamente por
una anulación escrita correctamente. Para obtener un ejemplo completamente funcional de anular "glob", estudie
la implementación de "File :: DosGlob" en la biblioteca estándar.

Cuando anula un incorporado, su reemplazo debe ser consistente (si es posible) con el
sintaxis nativa incorporada. Puede lograr esto utilizando un prototipo adecuado. Para obtener el
prototipo de una función incorporada anulable, utilice la función "prototipo" con un argumento de
"CORE :: nombre_builtin" (ver "prototipo" en perlfunc).

Sin embargo, tenga en cuenta que algunos componentes incorporados no pueden tener su sintaxis expresada por un prototipo (como
"sistema" o "chomp"). Si los anula, no podrá imitar completamente sus
sintaxis original.

Los elementos integrados "do", "require" y "glob" también se pueden anular, pero debido a la magia especial,
su sintaxis original se conserva, y no es necesario definir un prototipo para su
reemplazos. (Sin embargo, no puede anular la sintaxis "do BLOCK").

"require" tiene magia oscura adicional especial: si invoca su reemplazo "require" como
"require Foo :: Bar", en realidad recibirá el argumento "Foo / Bar.pm" en @_. Ver
"require" en perlfunc.

Y, como habrá notado en el ejemplo anterior, si anula "glob", el "<*>"
El operador glob también se anula.

De manera similar, anular la función "readline" también anula la E / S equivalente
operador " ". Además, anular" readpipe "también anula los operadores" `` "
y "qx //".

Por último, algunos elementos integrados (por ejemplo, "existe" o "grep") no se pueden anular.

Autocarga
Si llama a una subrutina que no está definida, normalmente obtendrá un resultado fatal inmediato.
error quejándose de que la subrutina no existe. (Lo mismo ocurre con las subrutinas que se utilizan
como métodos, cuando el método no existe en ninguna clase base del paquete de la clase).
Sin embargo, si se define una subrutina "AUTOLOAD" en el paquete o paquetes utilizados para localizar
la subrutina original, entonces esa subrutina "AUTOLOAD" se llama con los argumentos que
habría pasado a la subrutina original. El nombre completo del
la subrutina original aparece mágicamente en la variable global $ AUTOLOAD del mismo paquete
como la rutina "AUTOLOAD". El nombre no se pasa como un argumento ordinario porque, er,
bueno, solo porque, por eso. (Como excepción, una llamada a un método a una "importación" inexistente
o el método "unimport" simplemente se omite en su lugar. Además, si la subrutina AUTOLOAD es una
XSUB, hay otras formas de recuperar el nombre de la subrutina. Consulte "Carga automática con XSUB".
en perlguts para más detalles.)

Muchas rutinas "AUTOLOAD" se cargan en una definición para la subrutina solicitada usando eval (),
luego ejecute esa subrutina usando una forma especial de ir a() que borra el marco de pila de
la rutina "AUTOLOAD" sin dejar rastro. (Consulte la fuente del módulo estándar documentado
en Autocargador, por ejemplo.) Pero una rutina "AUTOLOAD" también puede simplemente emular la rutina
y nunca definirlo. Por ejemplo, supongamos que una función que no estaba definida
debería simplemente invocar "sistema" con esos argumentos. Todo lo que harías es:

sub CARGA AUTOMÁTICA {
mi $ programa = $ AUTOLOAD;
$ programa = ~ s /.* :: //;
sistema ($ programa, @_);
}
fecha();
quién soy');
ls ('- l');

De hecho, si declara previamente funciones que desea llamar de esa manera, ni siquiera necesita
paréntesis:

use subs qw (date who ls);
fecha;
quién soy";
ls '-l';

Un ejemplo más completo de esto es el módulo Shell en CPAN, que puede tratar indefinidos
llamadas a subrutinas como llamadas a programas externos.

Hay mecanismos disponibles para ayudar a los escritores de módulos a dividir sus módulos en autocargables
archivos. Consulte el módulo Autocargador estándar descrito en Autocargador y en AutoSplit, el
módulos SelfLoader estándar en SelfLoader, y el documento sobre cómo agregar funciones C a Perl
código en perlxs.

Subrutina Atributos
Una declaración o definición de subrutina puede tener una lista de atributos asociados.
Si una lista de atributos de este tipo está presente, se divide en los límites del espacio o de los dos puntos y
tratado como si se hubiera visto un "atributo de uso". Consulte los atributos para obtener detalles sobre lo que
Los atributos son compatibles actualmente. A diferencia de la limitación con el obsolescente "uso
attrs ", la sintaxis" sub: ATTRLIST "trabaja para asociar los atributos con un pre
declaración, y no solo con una definición de subrutina.

Los atributos deben ser válidos como nombres de identificadores simples (sin ninguna puntuación, otros
que el carácter '_'). Pueden tener una lista de parámetros adjunta, que solo está marcada
para saber si sus paréntesis ('(', ')') anidan correctamente.

Ejemplos de sintaxis válida (aunque se desconocen los atributos):

sub fnord (& \%): switch (10, foo (7,3)): caro;
sub plugh (): Feo ('\ ("): Malo;
sub xyzzy: _5x5 {...}

Ejemplos de sintaxis no válida:

sub fnord: switch (10, foo (); # () -cadena no balanceada
sub snoid: Ugly ('('); # () -cadena no balanceada
sub xyzzy: 5x5; # "5x5" no es un identificador válido
sub plugh: Y2 :: norte; # "Y2 :: norte" no es un identificador simple
sub snurt: foo + bar; # "+" ni dos puntos ni un espacio

La lista de atributos se pasa como una lista de cadenas constantes al código que asocia
ellos con la subrutina. En particular, el segundo ejemplo de sintaxis válida anterior
actualmente se ve así en términos de cómo se analiza e invoca:

usar atributos __PACKAGE__, \ & plugh, q [Ugly ('\ (")],' Bad ';

Para obtener más detalles sobre las listas de atributos y su manipulación, consulte atributos y
Atributo :: Controladores.

Use perlsub en línea usando los servicios de onworks.net


Servidores y estaciones de trabajo gratuitos

Descargar aplicaciones de Windows y Linux

Comandos de Linux

Ad




×
Anuncio
❤ ️Compre, reserve o adquiera aquí: sin costo, ayuda a mantener los servicios gratuitos.