Lo bueno, lo malo y lo feo de $ léxico en Perl 5.10+
global lexical (4)
A partir de Perl 5.10, ahora es posible ampliar léxicamente la variable de contexto $_
, ya sea explícitamente como my $_;
o en una construcción given / when
.
¿Alguien ha encontrado buenos usos del léxico $_
? ¿Hace las construcciones más simples / más seguras / más rápidas?
¿Qué pasa con las situaciones que hace más complicadas? ¿Ha introducido el léxico $_
algún error en tu código? (dado que las estructuras de control que escriben en $_
usarán la versión léxica si está dentro del alcance, esto puede cambiar el comportamiento del código si contiene alguna llamada de subrutina (debido a la pérdida del alcance dinámico))
Al final, me gustaría construir una lista que aclare cuándo usar $_
como léxico, como global o cuando no importa en absoluto.
NB: a partir de perl5-5.24
estas características experimentales ya no forman parte de perl .
En mi opinión, una de las grandes ventajas de la $_
léxica es el nuevo símbolo de prototipo.
Esto le permite especificar una subrutina para que tome un escalar o, si no se proporciona ninguno, tomará $_
.
Así que en lugar de escribir:
sub foo {
my $arg = @_ ? shift : $_;
# Do stuff with $_
}
Puedo escribir:
sub foo(_) {
my $arg = shift;
# Do stuff with $_ or first arg.
}
No es un gran cambio, pero es mucho más simple cuando quiero ese comportamiento. La remoción de la caldera es algo bueno.
Por supuesto, esto tiene el efecto de cambiar los prototipos de varios componentes integrados (por ejemplo, chr
), que pueden romper algún código.
En general, doy la bienvenida a $_
léxico. Me da una herramienta que puedo usar para limitar la información accidental y las extrañas interacciones entre las funciones. Si decido usar $_
en el cuerpo de una función, al lexicalizarla, puedo estar seguro de que, independientemente del código al que llame, $_
no se modificará en el código de llamada.
El alcance dinámico es interesante, pero en su mayor parte quiero un alcance léxico. Añadir a esto las complicaciones alrededor de $_
. He escuchado advertencias acerca de la inconveniencia de simplemente hacer local $_;
--que es mejor usar for ( $foo ) { }
lugar. El $_
Lexixized me da lo que quiero 99 veces de cada 100 cuando localizo $_
por cualquier medio. $_
Léxico hace que una característica de gran conveniencia y legibilidad sea más robusta.
La mayor parte de mi trabajo ha tenido que trabajar con Perl 5.8, por lo que no he tenido la alegría de jugar con $_
léxicos en proyectos más grandes. Sin embargo, parece que esto hará un largo camino para hacer que el uso de $_
más seguro, lo cual es bueno.
No he tenido ningún problema aquí, aunque tiendo a seguir una política de "No preguntes, no digas" cuando se trata de la magia de Perls. Es decir, generalmente no se espera que las rutinas se basen en sus compañeros que se atornillan con datos no léxicos como efecto secundario, ni que los dejen.
He probado el código con varias versiones 5.8 y 5.10 de perl, mientras uso un 5.6 que describe Camel para referencias ocasionales. No he tenido ningún problema. La mayoría de mis cosas fueron hechas originalmente para Perl 5.8.8.
Una vez encontré un issue (el error sería una palabra demasiado fuerte) que surgió cuando estaba jugando con el módulo Inline
. Este sencillo script:
use strict qw(vars subs);
for (''function'') {
$_->();
}
sub function {
require Inline;
Inline->bind(C => <<''__CODE__'');
void foo()
{
}
__CODE__
}
falla Modification of a read-only value attempted at /usr/lib/perl5/site_perl/5.10/Inline/C.pm line 380.
mensaje de error. En lo profundo de las Inline
internas del módulo Inline
hay una subrutina que quería modificar $_
, lo que lleva al mensaje de error anterior.
Utilizando
for my $_ (''function'') { ...
o declarar de otra manera my $_
es una solución viable a este problema.
(El módulo Inline
fue parcheado para solucionar este problema en particular).
[ Justificación: Una breve respuesta adicional con un resumen rápido para los recién llegados de perl que pueden pasar. Al buscar "tema léxico perl", uno puede terminar aquí.]
En este momento (2015) supongo que es de conocimiento general que la introducción del tema léxico ( my $_
y algunas características relacionadas) llevó a algunos comportamientos involuntarios difíciles de detectar y, por lo tanto, se marked como experimental y luego entró en una etapa de desaprobación. .
Resumen parcial de
#RT119315
: una sugerencia fue para algo comouse feature ''lextopic'';
para hacer uso de una nueva variable temática léxica:$^_
. Otro punto señalado fue que un " nombre implícito para el operador de topicalización ... distinto de$_
" funcionaría mejor cuando se combinara con funciones explícitamente léxicas ( por ejemplo,map
léxico olmap
). Si estos enfoques permitirían de alguna manera salvar el casogiven/when
no está claro. En la vida futura de las fases experimentales y de depreciación, tal vez algo pueda terminar viviendo en el río CPAN.