logo - perl pdf
¿Las características ocultas de Perl? (30)
Nuevas operaciones de bloques
Yo diría que la capacidad de expandir el lenguaje, crear operaciones de pseudobloque es una.
Usted declara el prototipo de un sub que indica que primero necesita una referencia de código:
sub do_stuff_with_a_hash (&/%) { my ( $block_of_code, $hash_ref ) = @_; while ( my ( $k, $v ) = each %$hash_ref ) { $block_of_code->( $k, $v ); } }
Luego puede llamarlo en el cuerpo como tal
use Data::Dumper; do_stuff_with_a_hash { local $Data::Dumper::Terse = 1; my ( $k, $v ) = @_; say qq(Hey, the key is "$k"!); say sprintf qq(Hey, the value is "%v"!), Dumper( $v ); } %stuff_for ;
( Data::Dumper::Dumper
es otra gema semioculta.) Observe que no necesita la palabra clave sub
al frente del bloque, o la coma antes del hash. Termina pareciéndose mucho a: map { } @list
Filtros de fuente
Además, hay filtros de fuente. Donde Perl te pasará el código para que puedas manipularlo. Tanto esto como las operaciones de bloque son cosas del tipo "no lo intentes en casa".
He hecho algunas cosas buenas con los filtros de origen, por ejemplo, como crear un lenguaje muy simple para verificar la hora, permitiendo frases cortas de Perl para tomar decisiones:
perl -MLib::DB -MLib::TL -e ''run_expensive_database_delete() if $hour_of_day < AM_7'';
Lib::TL
simplemente escaneará tanto las "variables" como las constantes, las creará y las sustituirá según sea necesario.
Nuevamente, los filtros de fuente pueden ser desordenados, pero son poderosos. Pero pueden ensuciar a los depuradores con algo terrible, e incluso las advertencias pueden imprimirse con los números de línea incorrectos. Dejé de usar Damian''s Switch porque el depurador perdería toda capacidad de decirme dónde estaba realmente. Pero descubrí que puedes minimizar el daño modificando pequeñas secciones de código, manteniéndolos en la misma línea.
Ganchos de señal
A menudo es suficiente, pero no es tan obvio. Aquí hay un manejador de dados que se aprovecha del anterior.
my $old_die_handler = $SIG{__DIE__};
$SIG{__DIE__}
= sub { say q(Hey! I''m DYIN'' over here!); goto &$old_die_handler; }
;
Eso significa que cada vez que algún otro módulo en el código quiera morir, deben acudir a usted (a menos que alguien más haga una sobrescritura destructiva en $SIG{__DIE__}
). Y se le puede notificar que alguien algo es un error.
Por supuesto, para cosas suficientes puedes simplemente usar un bloque END { }
, si todo lo que quieres hacer es limpiar.
overload::constant
Puede inspeccionar literales de cierto tipo en paquetes que incluyen su módulo. Por ejemplo, si usa esto en su sub de import
:
overload::constant
integer => sub {
my $lit = shift;
return $lit > 2_000_000_000 ? Math::BigInt->new( $lit ) : $lit
};
significará que cada número entero mayor a 2 mil millones en los paquetes de llamadas se cambiará a un objeto Math::BigInt
. (Ver overload::constant ).
Literales enteros agrupados
Mientras estamos en eso. Perl te permite dividir grandes cantidades en grupos de tres dígitos y obtener un entero analizable. Note 2_000_000_000
arriba para 2 billones.
¿Cuáles son algunas características del lenguaje realmente útiles pero esotéricas en Perl que realmente ha podido emplear para hacer un trabajo útil?
Pautas:
- Intenta limitar las respuestas al núcleo de Perl y no al CPAN
- Por favor dé un ejemplo y una breve descripción
Las funciones ocultas también se encuentran en las características ocultas de otros idiomas:
(Todos estos son de la respuesta de Corion )
- C
- Dispositivo de Duff
- Portabilidad y Estandaridad
- C#
- Citas para listas y cadenas delimitadas en espacios en blanco
- Espacios de nombres accesibles
- Java
- Initizadores Estáticos
- JavaScript
- Las funciones son ciudadanos de primera clase
- Alcance y cierre del bloque
- Llamando métodos y accesadores indirectamente a través de una variable
- Ruby
- Definición de métodos a través del código
- PHP
- Documentación en línea generalizada
- Métodos mágicos
- Referencias simbólicas
- Python
- Cambio de valor de una línea
- Posibilidad de reemplazar incluso las funciones principales con su propia funcionalidad
Otras características ocultas:
Operadores:
- El cuasi operador de bool
- El operador de flip-flop
- También se usa para la construcción de listas
- Los operadores
++
y unary trabajan en cadenas - El operador de repetición
- El operador de nave espacial
- El || operador (y // operador) para seleccionar entre un conjunto de opciones
- El operador de diamantes
- Casos especiales del operador
m//
- El "operador" de tilde-tilde
Citando constructos:
- El operador qw
- Las letras se pueden usar como delimitadores de comillas en construcciones q {}.
- Mecanismos de cotización
Sintaxis y nombres:
- Puede haber un espacio después de un sigilo
- Puede dar nombres numéricos subs con referencias simbólicas
- Comillas legales finales
- Literales enteros agrupados
- rebanadas de hash
- Rellenar teclas de un hash de una matriz
Módulos, Pragmas y opciones de línea de comandos:
- use estrictas y use advertencias
- Tacha de comprobación
- Uso esotérico de -n y -p
- CPAN
-
overload::constant
- IO :: módulo de la manija
- Compartimentos seguros
- Attributes
Variables:
- Autovivification
- La variable
$[
- tie
- Alcance dinámico
- Intercambio de variables con una sola declaración
Bucles y control de flujo:
Expresiones regulares:
Otras características:
- El depurador
- Bloques de código especiales como BEGIN, CHECK y END
- El bloque
DATA
- Nuevas operaciones de bloques
- Filtros de fuente
- Ganchos de señal
- map ( twice )
- Envoltura de funciones incorporadas
- La función
eof
- La función
dbmopen
- Transformando las advertencias en errores
Otros trucos y meta respuestas
Ver también:
Agregue soporte para archivos comprimidos a través de magic ARGV :
s{
^ # make sure to get whole filename
(
[^''] + # at least one non-quote
/. # extension dot
(?: # now either suffix
gz
| Z
)
)
/z # through the end
}{gzcat ''$1'' |}xs for @ARGV;
(comillas alrededor de $ _ necesarias para manejar los nombres de archivo con metacaracteres del shell en)
Ahora la característica <>
descomprimirá cualquier archivo @ARGV
que termine con ".gz" o ".Z":
while (<>) {
print;
}
Binario "x" es el operador de repetición :
print ''-'' x 80; # print row of dashes
También funciona con listas:
print for (1, 4, 9) x 3; # print 149149149
Comencemos fácil con el Operador de la nave espacial .
$a = 5 <=> 7; # $a is set to -1
$a = 7 <=> 5; # $a is set to 1
$a = 6 <=> 6; # $a is set to 0
Como Perl tiene casi todas las partes "esotéricas" de las otras listas, te diré una cosa que Perl no puede:
Lo único que Perl no puede hacer es tener URLs arbitrarias en su código, porque el operador //
se usa para expresiones regulares.
En caso de que no fuera obvio para usted qué características ofrece Perl, aquí hay una lista selectiva de las entradas que tal vez no sean totalmente obvias:
Portabilidad y estandarización : es probable que haya más computadoras con Perl que con un compilador de C
Una clase de manipulación de archivos / rutas - File :: Find funciona en incluso más sistemas operativos que .Net lo hace
Citas para listas y cadenas delimitadas en espacios en blanco : Perl le permite elegir citas casi arbitrarias para su lista y delimitadores de cadenas
Espacios de nombres accesibles - Perl tiene estos a través de asignaciones glob:
*My::Namespace:: = /%Your::Namespace
Inicializadores estáticos : Perl puede ejecutar código en casi todas las fases de compilación e instanciación de objetos, desde BEGIN
(análisis de código) hasta CHECK
(después del análisis de código) para import
(en módulo de importación) a new
(instanciación de objetos) a DESTROY
(destrucción de objetos) para END
(salida del programa)
Las funciones son ciudadanos de primera clase , como en Perl
Alcance y cierre del bloque : Perl tiene ambos
Llamando métodos y accesadores indirectamente a través de una variable - Perl también lo hace:
my $method = ''foo'';
my $obj = My::Class->new();
$obj->$method( ''baz'' ); # calls $obj->foo( ''baz'' )
Definir métodos a través del código : Perl también lo permite :
*foo = sub { print "Hello world" };
Documentación en línea generalizada: la documentación de Perl está en línea y probablemente en su sistema también
Métodos mágicos que se llaman cuando se llama a una función "inexistente": Perl lo implementa en la función AUTOLOAD
Referencias simbólicas : le aconsejamos que se mantenga alejado de estas. Ellos se comerán a tus hijos. Pero, por supuesto, Perl te permite ofrecer a tus hijos a los demonios sedientos de sangre.
Intercambio de valores de una línea : Perl permite la asignación de listas
Posibilidad de reemplazar incluso las funciones principales con su propia funcionalidad
use subs ''unlink'';
sub unlink { print ''No.'' }
o
BEGIN{
*CORE::GLOBAL::unlink = sub {print ''no''}
};
unlink($_) for @ARGV
El operador de flip-flop es útil para omitir la primera iteración al recorrer los registros (generalmente líneas) devueltos por un identificador de archivo, sin utilizar una variable de indicador:
while(<$fh>)
{
next if 1..1; # skip first record
...
}
Ejecute perldoc perlop
y busque "flip-flop" para obtener más información y ejemplos.
El operador de la palabra clave es una de mis cosas favoritas. Comparar:
my @list = (''abc'', ''def'', ''ghi'', ''jkl'');
y
my @list = qw(abc def ghi jkl);
Mucho menos ruido, más fácil para el ojo. Otra cosa realmente agradable sobre Perl, que realmente falla al escribir SQL, es que una coma final es legal:
print 1, 2, 3, ;
Eso parece extraño, pero no si aplica sangría al código de otra manera:
print
results_of_foo(),
results_of_xyzzy(),
results_of_quux(),
;
Agregar un argumento adicional a la llamada a la función no requiere que juegue con comas en las líneas anteriores o posteriores. El cambio de una sola línea no tiene impacto en las líneas que lo rodean.
Esto hace que sea muy agradable trabajar con funciones variadas. Esta es quizás una de las características más subestimadas de Perl.
Es simple citar casi cualquier tipo de cadena extraña en Perl.
my $url = q{http://my.url.com/any/arbitrary/path/in/the/url.html};
De hecho, los diversos mecanismos de cotización en Perl son bastante interesantes. Los mecanismos de cotización de Perge regex-like le permiten citar cualquier cosa, especificando los delimitadores. Puede usar casi cualquier carácter especial como #, /, o abrir / cerrar caracteres como (), [] o {}. Ejemplos:
my $var = q#some string where the pound is the final escape.#;
my $var2 = q{A more pleasant way of escaping.};
my $var3 = q(Others prefer parens as the quote mechanism.);
Mecanismos de cotización:
q: cita literal; solo el personaje que necesita ser escapado es el personaje final. qq: una cita interpretada; procesa variables y escapa caracteres. Ideal para cadenas que necesita citar:
my $var4 = qq{This "$mechanism" is broken. Please inform "$user" at "$email" about it.};
qx: Funciona como qq, pero luego lo ejecuta como un comando del sistema, de forma no interactiva. Devuelve todo el texto generado a partir de la salida estándar. (También sale la redirección, si es compatible con el SO). También se hace con comillas (el `carácter).
my $output = qx{type "$path"}; # get just the output
my $moreout = qx{type "$path" 2>&1}; # get stuff on stderr too
qr: interpreta como qq, pero luego lo compila como una expresión regular. Funciona con las diversas opciones en la expresión regular también. Ahora puede pasar la expresión regular como una variable:
sub MyRegexCheck {
my ($string, $regex) = @_;
if ($string)
{
return ($string =~ $regex);
}
return; # returns ''null'' or ''empty'' in every context
}
my $regex = qr{http://[/w]/.com/([/w]+/)+};
@results = MyRegexCheck(q{http://myurl.com/subpath1/subpath2/}, $regex);
qw: Un operador de cotizaciones muy, muy útil. Convierte un conjunto citado de palabras separadas en espacios en blanco en una lista. Ideal para completar datos en una prueba unitaria.
my @allowed = qw(A B C D E F G H I J K L M N O P Q R S T U V W X Y Z { });
my @badwords = qw(WORD1 word2 word3 word4);
my @numbers = qw(one two three four 5 six seven); # works with numbers too
my @list = (''string with space'', qw(eight nine), "a $var"); # works in other lists
my $arrayref = [ qw(and it works in arrays too) ];
Son geniales para usarlos cada vez que aclara las cosas. Para qx, qq yq, lo más probable es que use los operadores {}. El hábito más común de las personas que usan qw suele ser el operador (), pero a veces también se ve qw //.
Esta es una meta-respuesta, pero los archivos Perl Tips contienen todo tipo de trucos interesantes que se pueden hacer con Perl. El archivo de consejos anteriores está en línea para navegar, y se puede suscribir a través de la lista de correo o la alimentación atómica.
Algunos de mis consejos favoritos incluyen la construcción de ejecutables con PAR , el uso de autodie para lanzar excepciones automáticamente , y el uso de las construcciones de switch smart-match en Perl 5.10.
Divulgación: soy uno de los autores y mantenedores de Perl Tips, así que obviamente los considero muy apreciados. ;)
Hay muchas características no obvias en Perl.
Por ejemplo, ¿sabías que puede haber un espacio después de un sigilo?
$ perl -wle ''my $x = 3; print $ x''
3
¿O que puede dar nombres numéricos subs si utiliza referencias simbólicas?
$ perl -lwe ''*4 = sub { print "yes" }; 4->()''
yes
También está el operador cuasi "bool", que devuelve 1 para expresiones verdaderas y la cadena vacía para falso.
$ perl -wle ''print !!4''
1
$ perl -wle ''print !!"0 but true"''
1
$ perl -wle ''print !!0''
(empty line)
Otras cosas interesantes: con use overload
, puede sobrecargar literales y números de cadena (y, por ejemplo, convertirlos en BigInts o lo que sea).
Muchas de estas cosas están realmente documentadas en alguna parte, o siguen lógicamente las características documentadas, pero aún así algunas no son muy conocidas.
Actualización : Otra buena. Debajo de los q{...}
mencionaron construcciones de cotización, pero ¿sabías que puedes usar letras como delimitadores?
$ perl -Mstrict -wle ''print q bJet another perl hacker.b''
Jet another perl hacker.
Del mismo modo, puedes escribir expresiones regulares:
m xabcx
# same as m/abc/
La capacidad de analizar datos directamente pegados en un bloque de DATOS . No es necesario guardar en un archivo de prueba para abrirlo en el programa o similar. Por ejemplo:
my @lines = <DATA>;
for (@lines) {
print if /bad/;
}
__DATA__
some good data
some bad data
more good data
more good data
La cláusula continuar en bucles. Se ejecutará en la parte inferior de cada ciclo, incluso aquellos que están próximos.
while( <> ){
print "top of loop/n";
chomp;
next if /next/i;
last if /last/i;
print "bottom of loop/n";
}continue{
print "continue/n";
}
La declaración "para" se puede usar de la misma manera que "con" se usa en Pascal:
for ($item)
{
s/ / /g;
s/<.*?>/ /g;
$_ = join(" ", split(" ", $_));
}
Puede aplicar una secuencia de s /// operaciones, etc. a la misma variable sin tener que repetir el nombre de la variable.
NOTA: el espacio de no separación anterior (& nbsp;) ha ocultado Unicode en él para eludir el Margen de reducción. No copiar pegarlo :)
Los operadores ++ y unario no solo funcionan en números, sino también en cadenas.
my $_ = "a"
print -$_
impresiones -a
print ++$_
impresiones b
$_ = ''z''
print ++$_
imprime aa
Mi voto iría para los grupos (? {}) Y (?? {}) en las expresiones regulares de Perl. El primero ejecuta el código de Perl, ignorando el valor de retorno, el segundo ejecuta el código, usando el valor de retorno como una expresión regular.
No está realmente oculto, pero muchos programadores de Perl todos los días no conocen CPAN . Esto se aplica especialmente a las personas que no son programadores a tiempo completo o que no programan en Perl a tiempo completo.
Según la forma en que se implementan los conmutadores "-n"
y "-p"
en Perl 5, puede escribir un programa aparentemente incorrecto que incluya }{
:
ls |perl -lne ''print $_; }{ print "$. Files"''
que se convierte internamente a este código:
LINE: while (defined($_ = <ARGV>)) {
print $_; }{ print "$. Files";
}
Taint checking. Con la comprobación de manchas activada, Perl morirá (o advertirá, con -t
) si intentas pasar datos viciados (en términos generales, datos del exterior del programa) a una función insegura (abrir un archivo, ejecutar un comando externo, etc.) . Es muy útil cuando se escriben scripts setuid o CGI o cualquier cosa donde el script tenga mayores privilegios que la persona que lo alimenta.
Magic goto. goto &sub
realiza una llamada de cola optimizada.
El depurador.
use strict
y use warnings
. Estos pueden salvarte de un montón de errores tipográficos.
Una de mis funciones favoritas en Perl es usar el booleano ||
operador para seleccionar entre un conjunto de opciones.
$x = $a || $b;
# $x = $a, if $a is true.
# $x = $b, otherwise
Esto significa que uno puede escribir:
$x = $a || $b || $c || 0;
para tomar el primer valor verdadero de $a
, $b
y $c
, o un valor predeterminado de 0
caso contrario.
En Perl 5.10, también está el operador //
, que devuelve el lado izquierdo si está definido, y el lado derecho en caso contrario. A continuación, se selecciona el primer valor definido de $a
, $b
, $c
o 0
caso contrario:
$x = $a // $b // $c // 0;
Estos también se pueden usar con sus formas abreviadas, que son muy útiles para proporcionar valores predeterminados:
$x ||= 0; # If $x was false, it now has a value of 0. $x //= 0; # If $x was undefined, it now has a value of zero.
Cheerio,
Pablo
Autovivification . AFAIK no tiene otro idioma .
map , no solo porque hace que el código sea más expresivo, sino porque me dio un impulso para leer un poco más sobre esta "programación funcional".
Special code blocks such as BEGIN
, CHECK
and END
. They come from Awk, but work differently in Perl, because it is not record-based.
The BEGIN
block can be used to specify some code for the parsing phase; it is also executed when you do the syntax-and-variable-check perl -c
. For example, to load in configuration variables:
BEGIN {
eval {
require ''config.local.pl'';
};
if ($@) {
require ''config.default.pl'';
}
}
A bit obscure is the tilde-tilde "operator" which forces scalar context.
print ~~ localtime;
is the same as
print scalar localtime;
and different from
print localtime;
The "desperation mode" of Perl''s loop control constructs which causes them to look up the stack to find a matching label allows some curious behaviors which Test::More takes advantage of, for better or worse.
SKIP: {
skip() if $something;
print "Never printed";
}
sub skip {
no warnings "exiting";
last SKIP;
}
There''s the little known .pmc file. "use Foo" will look for Foo.pmc in @INC before Foo.pm. This was intended to allow compiled bytecode to be loaded first, but Module::Compile takes advantage of this to cache source filtered modules for faster load times and easier debugging.
The ability to turn warnings into errors.
local $SIG{__WARN__} = sub { die @_ };
$num = "two";
$sum = 1 + $num;
print "Never reached";
That''s what I can think of off the top of my head that hasn''t been mentioned.
The m//
operator has some obscure special cases:
- If you use
?
as the delimiter it only matches once unless you callreset
. - If you use
''
as the delimiter the pattern is not interpolated. - If the pattern is empty it uses the pattern from the last successful match.
The goatse operator *
:
$_ = "foo bar";
my $count =()= /[aeiou]/g; #3
o
sub foo {
return @_;
}
$count =()= foo(qw/a b c d/); #4
Funciona porque la asignación de lista en contexto escalar produce la cantidad de elementos en la lista que se está asignando.
*
Tenga en cuenta que realmente no es un operador
The null filehandle diamond operator <>
has its place in building command line tools. It acts like <FH>
to read from a handle, except that it magically selects whichever is found first: command line filenames or STDIN. Taken from perlop:
while (<>) {
... # code for each line
}
tie, the variable tying interface.
rename("$_.part", $_) for "data.txt";
renames data.txt.part to data.txt without having to repeat myself.
while(//G(/b/w*/b)/g) {
print "$1/n";
}
el anclaje / G. Hace calor