perlfaq7 - Online en la nube

Este es el comando perlfaq7 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


perlfaq7 - Problemas generales del lenguaje Perl

VERSION


Versión 5.021009

DESCRIPCIÓN


Esta sección trata sobre problemas generales del lenguaje Perl que no encajan claramente en ninguno de los
las otras secciones.

Can I get a BNF / yacc / RE para la Perl ¿idioma?
No hay BNF, pero puedes abrirte camino a través de la gramática yacc en perly.y en el
distribución de fuentes si eres particularmente valiente. La gramática se basa en muy inteligentes
tokenizando código, así que prepárate para aventurarte también en toke.c.

En palabras de Chaim Frenkel: "La gramática de Perl no se puede reducir a BNF. El trabajo de
el análisis sintáctico de perl se distribuye entre yacc, el lexer, el humo y los espejos ".

Qué están que todas these PS puntuación señales, y cómo do I know when a use ellos?
Son especificadores de tipo, como se detalla en perldata:

$ para valores escalares (número, cadena o referencia)
@ para matrices
% para hashes (matrices asociativas)
y para subrutinas (también conocidas como funciones, procedimientos, métodos)
* para todos los tipos de ese nombre de símbolo. En la versión 4 los usaste como
punteros, pero en las perls modernas solo puede usar referencias.

Hay un par de otros símbolos que probablemente encontrará que no son realmente
especificadores de tipo:

<> se utilizan para ingresar un registro desde un identificador de archivo.
\ toma una referencia a algo.

Tenga en cuenta que es ninguno el especificador de tipo para archivos ni el nombre del identificador. Está
el operador "<>" aplicado al identificador FILE. Lee una línea (bueno, registre - vea "$ /" en
perlvar) desde el identificador FILE en contexto escalar, o que todas líneas en el contexto de la lista. Cuándo
realizar abrir, cerrar o cualquier otra operación además de "<>" en archivos, o incluso al hablar
sobre el mango, haz no sea utilice los corchetes. Estos son correctos: "eof (FH)", "buscar (FH, 0, 2)"
y "copiando de STDIN a FILE".

Do I siempre nunca deben acudir a cotización inicial my instrumentos de cuerda or use punto y coma y comas?
Normalmente, no es necesario citar una palabra desnuda, pero en la mayoría de los casos probablemente debería (y
debe estar bajo "uso estricto"). Pero una clave de almohadilla que consiste en una palabra simple y la mano izquierda
operando al operador "=>" ambos cuentan como si estuvieran entrecomillados:

Esto es así
------------ ---------------
$ foo {línea} $ foo {'línea'}
bar => cosas 'bar' => cosas

El punto y coma final en un bloque es opcional, al igual que la coma final en una lista. Buen estilo
(ver estilo perl) dice que los ponga a excepción de las frases ingeniosas:

si ($ whoops) {salida 1}
mis @nums = (1, 2, 3);

si ($ whoops) {
salida 1;
}

mis @lines = (
"Allí Beren vino de las montañas frías",
"Y perdido vagó bajo las hojas",
);

Cómo do I omitir some volvemos ¿valores?
Una forma es tratar los valores devueltos como una lista e indexarlos:

$ dir = (getpwnam ($ usuario)) [7];

Otra forma es usar undef como un elemento en el lado izquierdo:

($ dev, $ ino, undef, undef, $ uid, $ gid) = stat ($ archivo);

También puede usar un sector de lista para seleccionar solo los elementos que necesita:

($ dev, $ ino, $ uid, $ gid) = (stat ($ archivo)) [0,1,4,5];

Cómo do I temporalmente bloquear advertencias?
Si está ejecutando Perl 5.6.0 o mejor, el pragma "use warnings" permite un control preciso de
qué advertencias se producen. Consulte perllexwarn para obtener más detalles.

{
sin advertencias; # desactivar temporalmente las advertencias
$ x = $ y + $ z; # Sé que estos pueden ser indefinidos
}

Además, puede habilitar y deshabilitar categorías de advertencias. Apagas el
categorías que desea ignorar y aún puede obtener otras categorías de advertencias. Ver
perllexwarn para obtener los detalles completos, incluidos los nombres de las categorías y la jerarquía.

{
no hay advertencias 'sin inicializar';
$ x = $ y + $ z;
}

Si tiene una versión anterior de Perl, la variable $ ^ W (documentada en perlvar) controla
advertencias de tiempo de ejecución para un bloque:

{
local $ ^ W = 0; # desactivar temporalmente las advertencias
$ x = $ y + $ z; # Sé que estos pueden ser indefinidos
}

Tenga en cuenta que, como todas las variables de puntuación, actualmente no puede usar mi() en $ ^ W, solo
local().

Qué está haciendo an ¿extensión?
Una extensión es una forma de llamar a código C compilado desde Perl. Leer perlxstut es bueno
lugar para obtener más información sobre las extensiones.

Por qué do Perl operadores deben acudir una experiencia diferente precedencia than C operadores?
De hecho, no lo hacen. Todos los operadores de C que Perl copia tienen la misma precedencia en Perl que
lo hacen en C. El problema es con los operadores que C no tiene, especialmente las funciones que
dar un contexto de lista a todo lo que está a su derecha, por ejemplo. print, chmod, exec, etc. Semejante
Las funciones se denominan "operadores de lista" y aparecen como tales en la tabla de precedencia en
perlop

Un error común es escribir:

desvincular $ archivo || morir "snafu";

Esto se interpreta como:

desvincular ($ archivo || die "snafu");

Para evitar este problema, coloque paréntesis adicionales o use la precedencia superbaja
operador "o":

(desvincular $ archivo) || morir "snafu";
desvincular $ archivo o morir "snafu";

Los operadores "ingleses" ("y", "o", "xor" y "not") deliberadamente tienen una precedencia inferior
que el de los operadores de lista para situaciones como la anterior.

Otro operador con sorprendente precedencia es la exponenciación. Se une más fuerte incluso
que menos unario, haciendo que "-2 ** 2" produzca un cuatro negativo y no uno positivo. Está
también de asociación a la derecha, lo que significa que "2 ** 3 ** 2" es dos elevado a la novena potencia, no ocho
al cuadrado

Aunque tiene la misma precedencia que en C, el operador "?:" De Perl produce un valor l. Esta
asigna $ x a $ if_true o $ if_false, dependiendo de la veracidad de $ maybe:

($ tal vez? $ if_true: $ if_false) = $ x;

Cómo do I declarar / crear a ¿estructura?
En general, no "declaras" una estructura. Solo usa un hash (probablemente anónimo)
referencia. Consulte perlref y perldsc para obtener más detalles. He aquí un ejemplo:

$ persona = {}; # nuevo hash anónimo
$ persona -> {EDAD} = 24; # establecer el campo EDAD en 24
$ persona -> {NOMBRE} = "Nat"; # establecer el campo NAME en "Nat"

Si buscas algo un poco más riguroso, prueba perlootut.

Cómo do I Para crear a ¿módulo?
perlnewmod es un buen lugar para comenzar, ignore los bits sobre la carga a CPAN si no lo hace
desea que su módulo esté disponible públicamente.

ExtUtils :: ModuleMaker y Module :: Starter también son buenos lugares para comenzar. Muchos autores de CPAN
ahora use Dist :: Zilla para automatizar tanto como sea posible.

Puede encontrar documentación detallada sobre los módulos en: perlmod, perlmodlib, perlmodstyle.

Si necesita incluir código C o interfaces de biblioteca C, use h2xs. h2xs creará el
estructura de distribución del módulo y los archivos de interfaz iniciales. perlxs y perlxstut
Explique los detalles.

Cómo do I adoptar or take más del a módulo ya on ¿CPAN?
Pídale al mantenedor actual que le convierta en co-mantenedor o le transfiera el módulo.

Si no puede comunicarse con el autor por algún motivo, comuníquese con los administradores de PAUSA en
módulos@perl.org quién puede ayudar, pero cada caso se trata por separado.

· Obtenga un inicio de sesión para el servidor de carga de autores de Perl (PAUSA) si aún no tiene uno:
<http://pause.perl.org>

· Escribir a módulos@perl.org explicando lo que hizo para ponerse en contacto con el mantenedor actual.
Los administradores de PAUSA también intentarán comunicarse con el mantenedor.

· Publique un mensaje público en un sitio con mucho tráfico anunciando su intención de tomar
sobre el módulo.

· Espera un poco. Los administradores de PAUSA no quieren actuar demasiado rápido en caso de que la
mantenedor está de vacaciones. Si no hay respuesta a la comunicación privada o al
publicación pública, un administrador de PAUSA puede transferírsela.

Cómo do I Para crear a ¿clase?
(contribución de brian d foy)

En Perl, una clase es solo un paquete y los métodos son solo subrutinas. Perl no consigue
más formal que eso y te permite configurar el paquete de la manera que te gusta (que
es decir, no configura nada para ti).

Vea también perlootut, un tutorial que cubre la creación de clases y perlobj.

Cómo puede I tell if a variable is ¿contaminado?
Puede utilizar las opciones contaminado() función del módulo Scalar :: Util, disponible en CPAN (o
incluido con Perl desde la versión 5.8.0). Consulte también "Lavado y detección de datos contaminados"
en perlsec.

Qué está haciendo a ¿cierre?
Los cierres están documentados en perlref.

de la Brecha es un término informático con un significado preciso pero difícil de explicar. Por lo general,
Los cierres se implementan en Perl como subrutinas anónimas con referencias duraderas a
variables léxicas fuera de su propio ámbito. Estos léxicos se refieren mágicamente a la
variables que existían cuando se definió la subrutina (enlace profundo).

Los cierres se utilizan con mayor frecuencia en lenguajes de programación donde puede tener el valor de retorno
de una función sea en sí misma una función, como puede hacerlo en Perl. Tenga en cuenta que algunos idiomas proporcionan
funciones anónimas pero no son capaces de proporcionar cierres adecuados: el lenguaje Python,
por ejemplo. Para obtener más información sobre cierres, consulte cualquier libro de texto sobre funcional
programación. Scheme es un lenguaje que no solo apoya sino que fomenta los cierres.

Aquí hay una función clásica de generación de funciones sin cierre:

sub add_function_generator {
return sub {shift () + shift ()};
}

my $ add_sub = add_function_generator ();
mi $ suma = $ add_sub -> (4,5); # $ sum es 9 ahora.

La subrutina anónima devuelta por add_function_generator () técnicamente no es un cierre
porque no se refiere a léxicos fuera de su propio ámbito. Usar un cierre te da una
función plantilla con algunos espacios de personalización que se dejaron para llenar más tarde.

Contraste esto con lo siguiente make_adder () función, en la que el anónimo devuelto
La función contiene una referencia a una variable léxica fuera del alcance de esa función.
sí mismo. Tal referencia requiere que Perl devuelva un cierre adecuado, bloqueando así
todo el tiempo el valor que tenía el léxico cuando se creó la función.

sub make_adder {
my $ addpiece = shift;
return sub {shift () + $ addpiece};
}

my $ f1 = hacer_sumador(20);
my $ f2 = hacer_sumador(555);

Ahora "$ f1 -> ($ n)" es siempre 20 más cualquier $ n que ingreses, mientras que "$ f2 -> ($ n)" es siempre
555 más cualquier $ n que ingrese. El $ addpiece en el cierre se mantiene.

Los cierres se utilizan a menudo con fines menos esotéricos. Por ejemplo, cuando quieres pasar
un poco de código en una función:

my $ line;
tiempo de espera (30, sub {$ línea = });

Si el código a ejecutar se ha pasado como una cadena, '$ línea = ', habría
no ha sido posible para lo hipotético se acabó el tiempo() función para acceder a la variable léxica $ line
de vuelta en el alcance de su llamador.

Otro uso de un cierre es hacer una variable de inversores privados a una subrutina nombrada, por ejemplo, un
contador que se inicializa en el momento de la creación del sub y solo se puede modificar desde
dentro del sub. Esto a veces se usa con un bloque BEGIN en archivos de paquete para asegurarse de que
La variable no se entromete durante la vida útil del paquete:

EMPEZAR {
my $ id = 0;
sub next_id {++ $ id}
}

Esto se discute con más detalle en perlsub; ver la entrada en Persistente Privado
Variables.

Qué is variable suicidio y cómo puede I evitar que?
Este problema se solucionó en perl 5.004_05, por lo que evitarlo significa actualizar su versión de
perla ;)

El suicidio variable es cuando usted pierde (temporal o permanentemente) el valor de una variable. Eso
es causado por el alcance a través de mi() y local() interactuando con cierres o con alias
para cada () variables de iterador y argumentos de subrutina. Solía ​​ser fácil inadvertidamente
pierde el valor de una variable de esta manera, pero ahora es mucho más difícil. Toma este código:

my $ f = 'foo';
sub T {
while ($ i ++ <3) {mi $ f = $ f; $ f. = "barra"; imprimir $ f, "\ n"}
}

T;
imprimir "Finalmente $ f \ n";

Si está experimentando un suicidio variable, ese "my $ f" en la subrutina no detecta un
copia nueva del $ f cuyo valor es 'foo'. La salida muestra que dentro de la subrutina el
el valor de $ f se filtra cuando no debería, como en este resultado:

Foobar
foobarbar
foobarbarbar
Finalmente foo

El $ f que tiene "bar" agregado tres veces debería ser un nuevo $ f "my $ f" debería crear un
nueva variable léxica cada vez que pasa por el bucle. El resultado esperado es:

Foobar
Foobar
Foobar
Finalmente foo

Cómo puede I pasar / volver a {Función, manejararchivo, Formación, Picadillo, Método, expresión regular}?
Debe pasar referencias a estos objetos. Consulte "Pasar por referencia" en perlsub para esto.
pregunta particular, y perlref para obtener información sobre referencias.

Pasar variables y funciones
Las variables y funciones regulares son bastante fáciles de pasar: simplemente pase una referencia a un
variable o función existente o anónima:

func (\ $ algún_escalar);

func (\ @algunos_arreglos);
func ([1 .. 10]);

func (\% some_hash);
func ({esto => 10, eso => ​​20});

func (\ & some_func);
func (sub {$ _ [0] ** $ _ [1]});

Pasar identificadores de archivos
A partir de Perl 5.6, puede representar identificadores de archivos con variables escalares que trata como
cualquier otro escalar.

abrir mi $ fh, $ nombre de archivo o morir "¡No se puede abrir $ nombre de archivo! $!";
func ($ fh);

función secundaria {
my $ pass_fh = turno;

my $ línea = <$ pasada_fh>;
}

Antes de Perl 5.6, tenía que usar las notaciones * FH o "\ * FH". Estos son
"typeglobs" - vea "Typeglobs y Filehandles" en perldata y especialmente "Pass by
Consulte "en perlsub para obtener más información.

Pasando expresiones regulares
Aquí hay un ejemplo de cómo pasar una cadena y una expresión regular para que coincida
contra. Construyes el patrón con el operador "qr //":

sub comparar {
my ($ val1, $ regex) = @_;
my $ retval = $ val1 = ~ / $ regex /;
return $ retval;
}
$ coincidencia = comparar ("viejo McDonald", qr / d. * D / i);

Pasando métodos
Para pasar un método de objeto a una subrutina, puede hacer esto:

call_a_lot (10, $ some_obj, "methname")
sub call_a_lot {
my ($ cuenta, $ widget, $ truco) = @_;
para (my $ i = 0; $ i <$ count; $ i ++) {
$ widget -> $ truco ();
}
}

O puede usar un cierre para agrupar el objeto, su llamada al método y sus argumentos:

my $ whatnot = sub {$ some_obj-> ofuscate (@args)};
func ($ lo que no);
función secundaria {
mi $ código = turno;
& $ código ();
}

También puede investigar el poder() método en la clase UNIVERSAL (parte del
distribución estándar de perl).

Cómo do I Para crear a estático ¿variable?
(contribución de brian d foy)

En Perl 5.10, declare la variable con "estado". La declaración "estado" crea el
variable léxica que persiste entre llamadas a la subrutina:

subcontador {estado $ cuenta = 1; $ count ++}

Puede falsificar una variable estática mediante el uso de una variable léxica que sale de su alcance. En
este ejemplo, usted define la subrutina "contador", y usa la variable léxica
$ count. Dado que envuelve esto en un bloque BEGIN, $ count se define en tiempo de compilación, pero también
sale del alcance al final del bloque BEGIN. El bloque BEGIN también asegura que el
subrutina y el valor que utiliza se define en tiempo de compilación para que la subrutina esté lista para
use como cualquier otra subrutina, y puede poner este código en el mismo lugar que otros
subrutinas en el texto del programa (es decir, al final del código, normalmente). La subrutina
"contador" todavía tiene una referencia a los datos y es la única forma de acceder al valor
(y cada vez que lo hace, aumenta el valor). Los datos en la porción de memoria definida por
$ count es privado para "contrarrestar".

EMPEZAR {
my $ count = 1;
contador secundario {$ count ++}
}

my $ inicio = contador ();

.... # código que llama a contador ();

mi $ final = contador ();

En el ejemplo anterior, creó una variable privada de función porque solo una función
recordó su referencia. Puede definir varias funciones mientras la variable está en
alcance, y cada función puede compartir la variable "privada". No es realmente "estático"
porque puede acceder a ella fuera de la función mientras la variable léxica está dentro del alcance, y
incluso crear referencias a él. En este ejemplo, "increment_count" y "return_count" comparten
La variable. Una función se suma al valor y la otra simplemente devuelve el valor. Ellos
pueden acceder a $ count y, dado que ha salido del alcance, no hay otra forma de
acceder a él.

EMPEZAR {
my $ count = 1;
sub increment_count {$ count ++}
sub return_count {$ count}
}

Para declarar una variable privada de archivo, todavía usa una variable léxica. Un archivo también es un
alcance, por lo que una variable léxica definida en el archivo no se puede ver desde ningún otro archivo.

Consulte "Variables privadas persistentes" en perlsub para obtener más información. La discusión de
Los cierres en perlref pueden ayudarlo aunque no usamos subrutinas anónimas en este
respuesta. Consulte "Variables privadas persistentes" en perlsub para obtener más detalles.

Qué está haciendo la la diferencia entre lugar de trabajo dinámico y léxico (estático) alcance? Entre local() y mi()?
"local ($ x)" guarda el antiguo valor de la variable global $ x y asigna un nuevo valor para
la duración de la subrutina lo cual is Visible in otros funciones , que son del que
subrutina. Esto se realiza en tiempo de ejecución, por lo que se denomina alcance dinámico. local() siempre afecta
variables globales, también llamadas variables de paquete o variables dinámicas.

"my ($ x)" crea una nueva variable que solo es visible en la subrutina actual. Esto es
hecho en tiempo de compilación, por lo que se llama ámbito léxico o estático. mi() siempre afecta
variables privadas, también llamadas variables léxicas o (incorrectamente) estáticas (con alcance ly)
variables.

Por ejemplo:

subvisible {
print "var tiene valor $ var \ n";
}

subdinámico {
local $ var = 'local'; # nuevo valor temporal para el todavía global
visible(); # variable llamada $ var
}

subléxico {
my $ var = 'privado'; # nueva variable privada, $ var
visible(); # (invisible fuera del subámbito)
}

$ var = 'global';

visible(); # impresiones globales
dinámica(); # impresiones locales
léxico(); # impresiones globales

Observe cómo en ningún momento se imprime el valor "privado". Eso es porque $ var solo tiene
ese valor dentro del bloque de la léxico() función, y está oculta de la llamada
subrutina.

En resumen, local() no crea lo que usted considera como variables locales privadas. Da un
variable global un valor temporal. mi() es lo que buscas si quieres privado
variables.

Consulte "Variables privadas a través de mi()"en perlsub y" Valores temporales a través de local()"en perlsub
para detalles insoportables.

Cómo puede I de la máquina a lugar de trabajo dinámico variable mientras a similar llamado léxico is in ¿alcance?
Si conoce su paquete, puede mencionarlo explícitamente, como en $ Some_Pack :: var. Nota
que la notación $ :: var es no sea el $ var dinámico en el paquete actual, sino más bien el
uno en el paquete "main", como si hubiera escrito $ main :: var.

use vars '$ var';
local $ var = "global";
my $ var = "léxico";

print "léxico es $ var \ n";
print "global es $ main :: var \ n";

Alternativamente, puede usar la directiva del compilador nuestro() para llevar una variable dinámica a
el ámbito léxico actual.

requieren 5.006; # nuestro () no existía antes de 5.6
use vars '$ var';

local $ var = "global";
my $ var = "léxico";

print "léxico es $ var \ n";

{
nuestro $ var;
print "global es $ var \ n";
}

Qué está haciendo la la diferencia entre profundo y superficial ¿Unión?
En enlace profundo, las variables léxicas mencionadas en subrutinas anónimas son las mismas
que estaban dentro del alcance cuando se creó la subrutina. En encuadernación superficial, son
cualesquiera variables con los mismos nombres que estén en el alcance cuando la subrutina es
llamado. Perl siempre usa enlaces profundos de variables léxicas (es decir, aquellas creadas con
mi()). Sin embargo, las variables dinámicas (también conocidas como variables globales, locales o de paquete)
efectivamente unida superficialmente. Considere esto como una razón más para no usarlos. Ver el
responder a "¿Qué es un cierre?".

Por qué no se "mi ($ foo) = <$ fh>; " Trabaja ¿derecho?
"my ()" y "local ()" dan contexto de lista al lado derecho de "=". El <$ fh> leído
operación, como muchas de las funciones y operadores de Perl, puede decir en qué contexto se
llamado y se comporta apropiadamente. En general, el escalar() la función puede ayudar. Esta
La función no hace nada con los datos en sí (contrariamente al mito popular), sino que dice su
argumento para comportarse de cualquier forma escalar. Si esa función no tiene
comportamiento escalar definido, esto por supuesto no le ayuda (como con ordenar()).

Sin embargo, para hacer cumplir el contexto escalar en este caso particular, simplemente debe omitir el
paréntesis:

local ($ foo) = <$ fh>; # INCORRECTO
local ($ foo) = escalar (<$ fh>); # OK
local $ foo = <$ fh>; # derecho

Probablemente debería usar variables léxicas de todos modos, aunque el problema es el mismo
aquí:

mi ($ foo) = <$ fh>; # INCORRECTO
my $ foo = <$ fh>; # derecho

Cómo do I redefinir a incorporado función, operador, or ¿método?
¿Por qué quieres hacer eso? :-)

Si desea anular una función predefinida, como open(), entonces tendrás que importar
la nueva definición de un módulo diferente. Consulte "Anulación de funciones integradas" en
perlsub.

Si desea sobrecargar un operador de Perl, como "+" o "**", entonces querrá usar el
pragma "use overload", documentado en overload.

Si habla de ocultar las llamadas a métodos en las clases principales, consulte "Anulación de métodos
y resolución de métodos "en perlootut.

Qué está haciendo la la diferencia entre llamar a función as & foo y foo ()?
(contribución de brian d foy)

Llamar a una subrutina como & foo sin paréntesis al final ignora el prototipo de "foo"
y le pasa el valor actual de la lista de argumentos, @_. He aquí un ejemplo; el bar"
subrutina llama a & foo, que imprime su lista de argumentos:

sub foo {print "Los argumentos en foo son: @_ \ n"; }

barra secundaria {& foo; }

barra ("a", "b", "c");

Cuando llamas a "bar" con argumentos, ves que "foo" tiene el mismo @_:

Los argumentos en foo son: abc

Llamar a la subrutina con paréntesis al final, con o sin argumentos, no usa
la corriente @_. Cambiar el ejemplo para poner paréntesis después de la llamada a "foo" cambia
el programa:

sub foo {print "Los argumentos en foo son: @_ \ n"; }

barra secundaria {& foo (); }

barra ("a", "b", "c");

Ahora la salida muestra que "foo" no obtiene el @_ de su llamador.

Los argumentos en foo son:

Sin embargo, el uso de "&" en la llamada aún anula el prototipo de "foo" si está presente:

sub foo ($$$) {imprimir "Los argumentos infoo son: @_ \ n"; }

sub bar_1 {& foo; }
sub bar_2 {& foo (); }
sub bar_3 {foo ($ _ [0], $ _ [1], $ _ [2]); }
# sub bar_4 {foo (); }
# bar_4 no se compila: "No hay suficientes argumentos para main :: foo en ..."

bar_1 ("a", "b", "c");
# Los argumentos en foo son: abc

bar_2 ("a", "b", "c");
# Los argumentos en foo son:

bar_3 ("a", "b", "c");
# Los argumentos en foo son: abc

El uso principal de la función de transferencia @_ es escribir subrutinas cuyo trabajo principal es
para llamar a otras subrutinas por usted. Para obtener más detalles, consulte perlsub.

Cómo do I Para crear a cambiar or case ¿declaración?
En Perl 5.10, use la construcción "dado cuando" descrita en perlsyn:

utilizar 5.010;

dado ($ cadena) {
cuando ('Fred') {di "¡Encontré a Fred!" }
cuando ('Barney') {di "¡Encontré a Barney!" }
cuando (/ Bamm-? Bamm /) {di "¡Encontré Bamm-Bamm!" }
predeterminado {di "¡No reconozco el nombre!" }
};

Si uno quiere usar Perl puro y ser compatible con versiones de Perl anteriores a 5.10, el
La respuesta general es usar "if-elsif-else":

para ($ variable_to_test) {
if (/ pat1 /) {} # haz algo
elsif (/ pat2 /) {} # haz algo más
elsif (/ pat3 /) {} # haz algo más
else {} # predeterminado
}

Aquí hay un ejemplo simple de un interruptor basado en la coincidencia de patrones, alineado para hacer
parece más una declaración de cambio. Haremos un condicional de múltiples vías basado en el tipo
de referencia almacenada en $ whatchamacallit:

INTERRUPTOR: para (ref $ whatchamacallit) {

/ ^ $ / && die "no es una referencia";

/ ESCALAR / && hacer {
print_scalar ($$ ref);
último INTERRUPTOR;
};

/ ARRAY / && do {
print_array (@ $ ref);
último INTERRUPTOR;
};

/ HASH / && do {
print_hash (% $ ref);
último INTERRUPTOR;
};

/ CODE / && do {
advertir "no se puede imprimir la función ref";
último INTERRUPTOR;
};

# DEFECTO

advertir "Tipo definido por el usuario omitido";

}

Consulte perlsyn para ver otros ejemplos de este estilo.

A veces debería cambiar las posiciones de la constante y la variable. Por ejemplo,
digamos que quería probar cuál de las muchas respuestas le dieron, pero en un caso-
forma insensible que también permite abreviaturas. Puede utilizar la siguiente técnica si
todas las cadenas comienzan con diferentes caracteres o si desea organizar las coincidencias para
que uno tiene prioridad sobre otro, ya que "ENVIAR" tiene prioridad sobre "DETENER" aquí:

chomp ($ respuesta = <>);
if ("SEND" = ~ / ^ \ Q $ answer / i) {print "La acción es enviar \ n"}
elsif ("STOP" = ~ / ^ \ Q $ answer / i) {print "La acción se detiene \ n"}
elsif ("ABORT" = ~ / ^ \ Q $ answer / i) {print "La acción es abortar \ n"}
elsif ("LIST" = ~ / ^ \ Q $ answer / i) {print "La acción es lista \ n"}
elsif ("EDIT" = ~ / ^ \ Q $ answer / i) {print "La acción es editar \ n"}

Un enfoque totalmente diferente es crear un hash de referencias de funciones.

mis% comandos = (
"feliz" => \ & alegría,
"triste", => \ & hosco,
"done" => sub {die "¡Nos vemos!" },
"enojado" => \ & enojado,
);

imprimir "¿Cómo estás?";
chomp ($ cadena = );
if ($ comandos {$ cadena}) {
$ comandos {$ cadena} -> ();
} Else {
imprimir "No existe tal comando: $ string \ n";
}

A partir de Perl 5.8, también se puede utilizar un módulo de filtro de fuente, "Switch", para obtener switch
y caso. Ahora se desaconseja su uso, porque no es totalmente compatible con el nativo.
cambio de Perl 5.10, y debido a que, como está implementado como un filtro de fuente, no
siempre funciona según lo previsto cuando se trata de una sintaxis compleja.

Cómo puede I catch accesos a indefinido variable, funciones, or ¿métodos?
El método AUTOLOAD, que se analiza en "Carga automática" en perlsub, le permite capturar llamadas a
funciones y métodos indefinidos.

Cuando se trata de variables indefinidas que activarían una advertencia en "advertencias de uso",
puede promover la advertencia a un error.

use advertencias FATAL => qw (sin inicializar);

Por qué no puedes a Método incluido in este vídeo mismo presentar be ¿encontró?
Algunas posibles razones: su herencia se está confundiendo, ha escrito mal el método
nombre, o el objeto es del tipo incorrecto. Consulte perlootut para obtener detalles sobre cualquiera de los
casos anteriores. También puede usar "print ref ($ object)" para averiguar la clase $ object era
bendecido en.

Otra posible razón de los problemas es que ha utilizado la sintaxis del objeto indirecto (p. Ej.,
"encuentra a Guru" Samy "") en el nombre de una clase antes de que Perl haya visto que tal paquete existe. Es
Lo más prudente es asegurarse de que todos sus paquetes estén definidos antes de comenzar a usarlos, lo que
tenga cuidado si utiliza la instrucción "use" en lugar de "require". Si no, asegúrese de
use notación de flechas (por ejemplo, "Guru-> find (" Samy ")") en su lugar. La notación de objetos se explica en
perlobj.

Asegúrese de leer sobre la creación de módulos en perlmod y los peligros de los objetos indirectos en
"Invocación de método" en perlobj.

Cómo puede I find out my corriente or llamar ¿paquete?
(contribución de brian d foy)

Para encontrar el paquete en el que se encuentra actualmente, utilice el literal especial "__PACKAGE__", como
documentado en perldata. Solo puede usar los literales especiales como tokens separados, por lo que
no puede interpolarlos en cadenas como puede hacerlo con variables:

mi $ paquete_actual = __PACKAGE__;
print "Estoy en el paquete $ current_package \ n";

Si desea encontrar el paquete que llama a su código, tal vez para brindar un mejor diagnóstico como
Carp lo hace, use el "llamador" integrado:

subfoo {
mis @argumentos = ...;
my ($ paquete, $ nombre de archivo, $ línea) = llamador;

print "Me llamaron desde el paquete $ paquete \ n";
);

De forma predeterminada, su programa se inicia en el paquete "main", por lo que siempre estará en algún paquete.

Esto es diferente de averiguar el paquete en el que se ha bendecido un objeto, lo que podría no
ser el paquete actual. Para eso, use "bendito" de Scalar :: Util, parte del estándar
Biblioteca desde Perl 5.8:

use Scalar :: Util qw (bendito);
my $ object_package = bendito ($ objeto);

Sin embargo, la mayoría de las veces, no debería importarle en qué paquete se bendiga un objeto, ya que
siempre que afirme heredar de esa clase:

my $ is_right_class = eval {$ objeto-> isa ($ paquete)}; # verdadero o falso

Y, con Perl 5.10 y versiones posteriores, no es necesario comprobar si hay una herencia para ver si
El objeto puede manejar un rol. Para eso, puedes usar "DOES", que viene de "UNIVERSAL":

my $ class_does_it = eval {$ object-> DOES ($ role)}; # verdadero o falso

Puede reemplazar con seguridad "isa" por "HACE" (aunque lo contrario no es cierto).

Cómo puede I comentario out a large bloquear of Perl código?
(contribución de brian d foy)

La forma rápida y sucia de comentar más de una línea de Perl es rodear esas
líneas con directivas Pod. Tienes que poner estas directivas al principio de la línea.
y en algún lugar donde Perl espera una nueva declaración (por lo que no en medio de declaraciones como
los comentarios). Termina el comentario con "= cortar", terminando la sección Pod:

= vaina

my $ objeto = NotGonnaHappen-> new ();

ignored_sub ();

$ wont_be_assigned = 37;

= cortar

El método rápido y sucio solo funciona bien cuando no planea dejar el código comentado
en la fuente. Si aparece un analizador de pod, su comentario de varias líneas aparecerá en
la traducción de la vaina. También hay una mejor manera de ocultarlo de los analizadores de Pod.

La directiva "= begin" puede marcar una sección para un propósito particular. Si el analizador de Pod
no quiere manejarlo, simplemente lo ignora. Etiqueta los comentarios con "comentario". Terminar el
comentar usando "= fin" con la misma etiqueta. Aún necesita el "= cortar" para volver a Perl
código del comentario del Pod:

= comenzar comentario

my $ objeto = NotGonnaHappen-> new ();

ignored_sub ();

$ wont_be_assigned = 37;

= comentario final

= cortar

Para obtener más información sobre Pod, consulte perlpod y perlpodspec.

Cómo do I limpiar a ¿paquete?
Utilice este código, proporcionado por Mark-Jason Dominus:

sub paquete_depuración {
no hay "referencias" estrictas;
mi $ paquete = turno;
die "No debería eliminar el paquete principal"
if $ paquete eq "" || $ paquete eq "principal";
my $ alijo = * {$ paquete. '::'}{PICADILLO};
mi $ nombre;
foreach $ nombre (claves% $ alijo) {
my $ fullname = $ paquete. '::'. $ nombre;
# Deshazte de todo lo que tenga ese nombre.
undef $$ fullname;
undef @ $ nombre completo;
undef% $ nombre completo;
undef & $ fullname;
undef * $ nombre completo;
}
}

O, si está usando una versión reciente de Perl, puede usar el
Símbolo :: delete_package () función en su lugar.

Cómo puede I use a variable as a variable ¿nombre?
Los principiantes a menudo piensan que quieren que una variable contenga el nombre de una variable.

$ fred = 23;
$ varname = "fred";
++ $$ varname; # $ fred ahora 24

Esto funciona sometimes, pero es una muy mala idea por dos razones.

La primera razón es que esta técnica único funciona on global las variables. Eso significa que si
$ fred es una variable léxica creada con mi() en el ejemplo anterior, el código no funcionaría
en absoluto: accedería accidentalmente al global y omitiría el léxico privado
en total. Las variables globales son malas porque pueden colisionar fácilmente de forma accidental y en
en general, para un código no escalable y confuso.

Las referencias simbólicas están prohibidas bajo el pragma "use estricto". No son verdad
referencias y, en consecuencia, no se cuentan por referencias ni se recolectan como basura.

La otra razón por la que usar una variable para contener el nombre de otra variable es una mala idea
es que la pregunta a menudo surge de una falta de comprensión de las estructuras de datos de Perl,
particularmente hashes. Al usar referencias simbólicas, solo está usando el paquete
hash de tabla de símbolos (como% main: :) en lugar de un hash definido por el usuario. La solución es usar
su propio hash o una referencia real en su lugar.

$ USER_VARS {"fred"} = 23;
my $ varname = "fred";
$ USER_VARS {$ varname} ++; # no $$ varname ++

Allí estamos usando el hash% USER_VARS en lugar de referencias simbólicas. A veces esto
aparece al leer cadenas del usuario con referencias variables y con ganas de expandir
a los valores de las variables de su programa perl. Esta también es una mala idea porque
fusiona el espacio de nombres direccionable por el programa y el direccionable por el usuario. En vez de
leer una cadena y expandirla al contenido real de las propias variables de su programa:

$ str = 'esto tiene $ fred y $ barney en él';
$ str = ~ s / (\ $ \ w +) / $ 1 / eeg; # necesita evaluación doble

sería mejor mantener un hash como% USER_VARS y tener referencias variables
en realidad se refieren a entradas en ese hash:

$ str = ~ s / \ $ (\ w +) / $ USER_VARS {$ 1} / g; # no / e aquí en absoluto

Eso es más rápido, más limpio y más seguro que el enfoque anterior. Por supuesto, no es necesario
use un signo de dólar. Puede usar su propio esquema para hacerlo menos confuso, como entre corchetes
símbolos de porcentaje, etc.

$ str = 'esto tiene% fred% y% barney% en él';
$ str = ~ s /% (\ w +)% / $ USER_VARS {$ 1} / g; # no / e aquí en absoluto

Otra razón por la que la gente a veces piensa que quiere que una variable contenga el nombre de un
variable es que no saben cómo construir estructuras de datos adecuadas usando hashes. Para
ejemplo, digamos que querían dos hashes en su programa:% fred y% barney, y que
querían usar otra variable escalar para referirse a ellos por su nombre.

$ nombre = "fred";
$$ nombre {ESPOSA} = "wilma"; # set% fred

$ nombre = "barney";
$$ nombre {ESPOSA} = "betty"; # set% barney

Esta sigue siendo una referencia simbólica, y todavía está cargada con los problemas enumerados.
sobre. Sería mucho mejor escribir:

$ gente {"fred"} {ESPOSA} = "wilma";
$ gente {"barney"} {ESPOSA} = "betty";

Y solo use un hash multinivel para empezar.

Las únicas veces que absolutamente deben usar referencias simbólicas es cuando realmente debes
consulte la tabla de símbolos. Esto puede deberse a que es algo que uno no puede tomar en serio.
referencia a, como un nombre de formato. Hacerlo también puede ser importante para las llamadas a métodos,
ya que estos siempre pasan por la tabla de símbolos para su resolución.

En esos casos, debería desactivar los "refs estrictos" temporalmente para que pueda jugar con
la tabla de símbolos. Por ejemplo:

@colors = qw (rojo azul verde amarillo naranja violeta violeta);
para mi $ nombre (@colors) {
sin "referencias" estrictas; # renegar por el bloqueo
* $ nombre = sub {" @_ "};
}

Todas esas funciones (rojo(), azul(), verde(), etc.) parecen estar separados, pero el verdadero
En realidad, el código del cierre se compiló solo una vez.

Entonces, a veces es posible que desee utilizar referencias simbólicas para manipular la tabla de símbolos
directamente. Esto no importa para formatos, identificadores y subrutinas, porque son
siempre global - no puedes usar mi() en ellos. Sin embargo, para escalares, matrices y hashes, y
generalmente para subrutinas, probablemente solo desee usar referencias duras.

Qué "malo Interprete" significa?
(contribución de brian d foy)

El mensaje de "mal intérprete" proviene del shell, no de Perl. El mensaje real puede variar
dependiendo de su plataforma, shell y configuración regional.

Si ve "mal intérprete - no existe tal archivo o directorio", la primera línea en su perl
script (la línea "shebang") no contiene la ruta correcta a perl (o cualquier otro programa
capaz de ejecutar scripts). A veces, esto sucede cuando mueve el guión de una
máquina a otra y cada máquina tiene una ruta diferente a perl--/ usr / bin / perl y no
/ usr / local / bin / perl, por ejemplo. También puede indicar que la máquina de origen tiene CRLF
terminadores de línea y la máquina de destino solo tiene LF: el shell intenta encontrar
/ usr / bin / perl, pero no puedo.

Si ve "intérprete incorrecto: Permiso denegado", debe hacer que su secuencia de comandos sea ejecutable.

En cualquier caso, aún debería poder ejecutar los scripts con perl explícitamente:

% secuencia de comandos perl.pl

Si recibe un mensaje como "perl: comando no encontrado", perl no está en su RUTA, lo que podría
También significa que la ubicación de Perl no es donde usted lo espera, por lo que debe ajustar su
línea shebang.

Do I necesite a recompilar XS módulos when there is a el cambio in la C ¿biblioteca?
(contribución de Alex Beamish)

Si la nueva versión de la biblioteca C es compatible con ABI (esa es la interfaz binaria de la aplicación
compatible) con la versión desde la que está actualizando y si la versión de la biblioteca compartida
no cambió, no debería ser necesaria una nueva compilación.

AUTOR Y DERECHOS DE AUTOR


Copyright (c) 1997-2013 Tom Christiansen, Nathan Torkington y otros autores como se indica.
Todos los derechos reservados.

Esta documentación es gratuita; puedes redistribuirlo y / o modificarlo en los mismos términos
como el propio Perl.

Independientemente de su distribución, todos los ejemplos de código de este archivo se colocan en
el dominio público. Se le permite y se le anima a utilizar este código en sus propios programas.
por diversión o con fines de lucro como mejor le parezca. Un simple comentario en el código que da crédito sería
cortés pero no es obligatorio.

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



Últimos programas en línea de Linux y Windows