variable lc_all en_us perl scoping

lc_all - ¿Cuál es la diferencia entre mi y local en Perl?



path environment variable ubuntu (14)

Estoy viendo que ambos se usan en este script que estoy tratando de depurar y la literatura no está clara. ¿Alguien puede desmitificar esto para mí?


"mis" variables son visibles solo en el bloque de código actual. las variables "locales" también son visibles donde quiera que hayan estado antes. Por ejemplo, si dices "my $ x"; y llama a una subfunción, no puede ver esa variable $ x. Pero si dices "local $ /" (para anular el valor del separador de registros), entonces cambia la forma en que funciona la lectura de archivos en cualquier función que llame.

En la práctica, casi siempre quiere "mi", no "local".


Alcance dinámico. Es un concepto limpio. Muchas personas no lo usan ni lo entienden.

Básicamente piense en my como crear y anclar una variable a un bloque de {}, AKA scope.

my $foo if (true); # $foo lives and dies within the if statement.

Entonces, my variable es a lo que estás acostumbrado. mientras que con alcance dinámico $ var puede declararse en cualquier lugar y utilizarse en cualquier lugar. Entonces, con un servidor local básicamente suspendes el uso de esa variable global y usas un "valor local" para trabajar con él. Por lo tanto, local crea un alcance temporal para una variable temporal.

$var = 4; print $var, "/n"; &hello; print $var, "/n"; # subroutines sub hello { local $var = 10; print $var, "/n"; &gogo; # calling subroutine gogo print $var, "/n"; } sub gogo { $var ++; }

Esto debería imprimir:

4 10 11 4


Bueno, Google realmente funciona para usted en este caso: http://www.perlmonks.org/?node_id=94007

Desde el enlace:

Resumen rápido: ''mi'' crea una nueva variable, ''local'' modifica temporalmente el valor de una variable.

es decir, ''local'' cambia temporalmente el valor de la variable , pero solo dentro del alcance en el que existe.

Generalmente uso mi, es más rápido y no hace nada raro.


Citando de Learning Perl :

Pero local es mal llamado, o al menos engañosamente nombrado. Nuestro amigo Chip Salzenberg dice que si alguna vez tiene la oportunidad de regresar a una máquina del tiempo hasta 1986 y darle un consejo a Larry, le diría a Larry que llame a local con el nombre "guardar" en su lugar. [14] Esto se debe a que, de hecho, el local guardará el valor de la variable global dada, por lo que posteriormente se restaurará automáticamente a la variable global. (Así es: ¡estas llamadas variables "locales" son en realidad globales!) Este mecanismo de guardar y restaurar es el mismo que ya hemos visto dos veces, en la variable de control de un bucle foreach, y en el @_ matriz de parámetros de subrutina.

Entonces, local guarda el valor actual de una variable global y luego lo configura en alguna forma de valor vacío. A menudo verá que solía sorber un archivo completo, en lugar de llevar solo una línea:

my $file_content; { local $/; open IN, "foo.txt"; $file_content = <IN>; }

Llamando local $/ establece el separador de registros de entrada (el valor en el que Perl deja de leer una "línea") a un valor vacío, haciendo que el operador de nave espacial lea todo el archivo, para que nunca llegue al separador de registros de entrada.


Creo que la manera más fácil de recordarlo es de esta manera. MY crea una nueva variable. LOCAL cambia temporalmente el valor de una variable existente.


Del man perlsub :

A diferencia de las variables dinámicas creadas por el operador local, las variables léxicas declaradas con mi están totalmente ocultas del mundo exterior, incluidas las subrutinas llamadas.

Entonces, simplificando demasiado, my hace que tu variable sea visible solo donde está declarada. local hace visible en la pila de llamadas también. Por lo general, querrás usar my lugar de local .


El ejemplo de dinomite de usar local para redefinir el delimitador de registros es la única vez que me he encontrado con mucha programación perl. Vivo en un entorno nicho perl [programación de seguridad], pero en realidad es un ámbito que rara vez se usa en mi experiencia.


La respuesta corta es que my marca una variable como privada en un ámbito léxico, y local marca una variable como privada en un ámbito dinámico.

Es más fácil de entender, ya que crea una variable local en el sentido habitual. Se ha creado una nueva variable y solo se puede acceder a ella dentro del bloque léxico delimitador, que generalmente está marcado con llaves. Existen algunas excepciones a la regla de llaves, tales como:

foreach my $x (@foo) { print "$x/n"; }

Pero eso es solo Perl haciendo lo que quieres decir. Normalmente tienes algo como esto:

sub Foo { my $x = shift; print "$x/n"; }

En ese caso, $x es privado para la subrutina y su alcance está encerrado entre llaves. Lo que hay que notar, y este es el contraste con lo local , es que el alcance de una de my variables se define con respecto a su código tal como está escrito en el archivo. Es un fenómeno de tiempo de compilación.

Para entender local , debe pensar en términos de la pila de llamadas de su programa mientras se está ejecutando. Cuando una variable es local , se redefine desde el punto en el que la instrucción local ejecuta para todo lo que está debajo de la pila, hasta que devuelve la pila a la persona que llama del bloque que contiene el local .

Esto puede ser confuso al principio, así que considere el siguiente ejemplo.

sub foo { print "$x/n"; } sub bar { local $x; $x = 2; foo(); } $x = 1; foo(); # prints ''1'' bar(); # prints ''2'' because $x was localed in bar foo(); # prints ''1'' again because local from foo is no longer in effect

Cuando se llama a foo la primera vez, ve el valor global de $x que es 1. Cuando se llama a la bar y se ejecuta local $x , eso redefine el $x global en la pila. Ahora cuando se llama a foo desde la bar , ve el nuevo valor de 2 por $x . Hasta ahora eso no es muy especial, porque lo mismo hubiera sucedido sin la llamada a local . La magia es que cuando la bar vuelve, salimos del alcance dinámico creado por local $x y el $x global anterior vuelve al alcance. Entonces, para la llamada final de foo , $x es 1.

Casi siempre querrás usar my , ya que eso te da la variable local que estás buscando. Una vez en una luna azul, el local es realmente útil para hacer cosas geniales.


Mire el siguiente código y su resultado para comprender la diferencia.

our $name = "Abhishek"; sub sub1 { print "/nName = $name/n"; local $name = "Abhijeet"; &sub2; &sub3; } sub sub2 { print "/nName = $name/n"; } sub sub3 { my $name = "Abhinav"; print "/nName = $name/n"; } &sub1;

La salida es:

Name = Abhishek Name = Abhijeet Name = Abhinav



Tu confusión es comprensible. El alcance léxico es bastante fácil de entender, pero el alcance dinámico es un concepto inusual. La situación empeora por los nombres my y local siendo algo inexactos (o al menos poco intuitivos) por razones históricas.

my declara una variable léxica, una que es visible desde el punto de declaración hasta el final del bloque adjunto (o archivo). Es completamente independiente de cualquier otra variable con el mismo nombre en el resto del programa. Es privado para ese bloque.

local , por otro lado, declara un cambio temporal en el valor de una variable global. El cambio finaliza al final del alcance adjunto, pero la variable, que es global, es visible en cualquier parte del programa.

Como regla general, utilice my para declarar sus propias variables y local para controlar el impacto de los cambios en las variables integradas de Perl.

Para una descripción más completa, consulte el artículo de Mark Jason Dominus Cómo afrontar el alcance .


local es un método de localización más antiguo, desde los tiempos en que Perl solo tenía un alcance dinámico. El alcance léxico es mucho más natural para el programador y mucho más seguro en muchas situaciones. mis variables pertenecen al alcance (bloque, paquete o archivo) en el que se declaran.

las variables locales en realidad pertenecen a un espacio de nombres global. Si se refiere a una variable $ x con local, en realidad se está refiriendo a $ main :: x, que es una variable global. Contrariamente a lo que su nombre implica, todas las local hace es empujar un nuevo valor en una pila de valores para $ main :: x hasta el final de este bloque, momento en el que se restaurará el valor anterior. Esa es una característica útil en sí misma, pero no es una buena manera de tener variables locales por una serie de razones (¡piense qué pasa cuando tiene hilos! Y piense qué sucede cuando llama a una rutina que realmente quiere usar un sistema global que ¡has localizado!). Sin embargo, era la única forma de tener variables que parecían variables locales en los malos viejos tiempos anteriores a Perl 5. Todavía estamos atrapados con eso.


http://perldoc.perl.org/perlsub.html#Private-Variables-via-my()

A diferencia de las variables dinámicas creadas por el operador local, las variables léxicas declaradas con mi están totalmente ocultas del mundo exterior, incluidas las subrutinas llamadas. Esto es cierto si es la misma subrutina llamada desde sí misma o en otro lugar: cada llamada obtiene su propia copia.

http://perldoc.perl.org/perlsub.html#Temporary-Values-via-local()

Un local modifica sus variables listadas para que sean "locales" para el bloque adjunto, eval, o para FILE --y para cualquier subrutina llamada desde dentro de ese bloque. Un local simplemente da valores temporales a variables globales (significa paquete). No crea una variable local. Esto se conoce como alcance dinámico. El alcance léxico está hecho con mi, que funciona más como las autodeclaraciones de C.

No creo que esto no sea del todo claro, aparte de decir que por "local al bloque circundante", lo que significa es que el valor original se restaura cuando se sale del bloque.


&s; sub s() { local $s="5"; &b; print $s; } sub b() { $s++; }

El script anterior imprime 6.

Pero si cambiamos el local a mi, se imprimirá 5.

Esta es la diferencia. Sencillo.