Sé lo que my
hay en Perl. Define una variable que existe solo en el ámbito del bloque en el que se define. ¿Qué our
hacer?
¿Cómo our
difiere de my
?
Gran pregunta: ¿en qué se our
diferencia my
y qué hace our
?
En resumen:
Disponible desde Perl 5, my
es una forma de declarar variables que no son paquetes, que son:
$package_name::variable
.Por otro lado, las our
variables son variables de paquete y, por lo tanto, automáticamente:
$package_name::variable
.Declarar una variable con le our
permite predefinir variables para usarlas use strict
sin recibir advertencias tipográficas o errores en tiempo de compilación. Desde Perl 5.6, ha reemplazado el obsoleto use vars
, que solo tenía un alcance de archivo y no tenía un alcance léxico tal como está our
.
Por ejemplo, el nombre formal y calificado para la variable $x
dentro package main
es $main::x
. La declaración le our $x
permite usar la $x
variable básica sin penalización (es decir, sin un error resultante), en el alcance de la declaración, cuando el script usa use strict
o use strict "vars"
. El alcance puede ser uno, o dos, o más paquetes, o un bloque pequeño.
local
no crea variables. No se relaciona conmy
your
en absoluto.local
respalda temporalmente el valor de la variable y borra su valor actual.our
Las variables no son variables de paquete. No son de ámbito global, sino variables de ámbito léxico al igual que lasmy
variables. Se puede ver que en el siguiente programa:package Foo; our $x = 123; package Bar; say $x;
. Si desea "declarar" una variable de paquete, debe usarlause vars qw( $x );
.our $x;
declara una variable de ámbito léxico con alias a la variable del mismo nombre en el paquete en el queour
se compiló.Los enlaces PerlMonks y PerlDoc de cartman y Olafur son una gran referencia: a continuación se muestra mi resumen:
my
las variables tienen un ámbito léxico dentro de un solo bloque definido por{}
o dentro del mismo archivo si no está en{}
s. No son accesibles desde paquetes / subrutinas definidas fuera del mismo ámbito / bloque léxico.our
las variables se definen dentro de un paquete / archivo y son accesibles desde cualquier código queuse
orequire
ese paquete / archivo: los conflictos de nombre se resuelven entre paquetes anteponiendo el espacio de nombres apropiado.Solo para redondearlo, las
local
variables tienen un alcance "dinámico", que difiere de lasmy
variables en que también son accesibles desde subrutinas llamadas dentro del mismo bloque.fuente
my
variables tienen un alcance [...] léxico dentro del mismo archivo si no están en{}
s". Eso fue útil para mí, gracias.Un ejemplo:
fuente
Hacer frente a Scoping es una buena descripción de las reglas de alcance de Perl. Es lo suficientemente viejo que
our
no se discute en el cuerpo del texto. Se trata en las Notas sección de al final.El artículo habla sobre las variables del paquete y el alcance dinámico y cómo difiere de las variables léxicas y el alcance léxico.
fuente
my
se usa para variables locales, mientras queour
se usa para variables globales.Más lectura en Variable Scoping en Perl: lo básico .
fuente
${^Potato}
es global Se refiere a la misma variable independientemente de dónde la use.Alguna vez encontré algunas trampas sobre declaraciones léxicas en Perl que me confundieron, que también están relacionadas con esta pregunta, así que solo agrego mi resumen aquí:
1. Definición o declaración?
La salida es
var: 42
. Sin embargo, no podríamos decir silocal $var = 42;
es una definición o declaración. Pero qué tal esto:El segundo programa arrojará un error:
$var
no está definido, lo que significa quelocal $var;
es solo una declaración! Antes de usarlocal
para declarar una variable, asegúrese de que esté definida como una variable global previamente.¿Pero por qué esto no fallará?
La salida es:
var: 42
.Eso es porque
$a
, además de$b
, es una variable global predefinida en Perl. ¿Recuerdas la función de clasificación ?2. ¿Léxico o global?
Era un programador en C antes de comenzar a usar Perl, por lo que el concepto de variables léxicas y globales me parece sencillo: solo corresponde a las variables automáticas y externas en C. Pero hay pequeñas diferencias:
En C, una variable externa es una variable definida fuera de cualquier bloque de funciones. Por otro lado, una variable automática es una variable definida dentro de un bloque de funciones. Me gusta esto:
Mientras que en Perl, las cosas son sutiles:
La salida es
var: 42
.$var
es una variable global incluso si está definida en un bloque de funciones! En realidad, en Perl, cualquier variable se declara como global de forma predeterminada.La lección es agregar siempre
use strict; use warnings;
al comienzo de un programa Perl, lo que obligará al programador a declarar explícitamente la variable léxica, para que no nos equivoquemos por algunos errores que se dan por sentados.fuente
El perldoc tiene una buena definición de nuestro.
fuente
Esto solo está algo relacionado con la pregunta, pero acabo de descubrir un poco (para mí) oscuro sintaxis de Perl que puedes usar con "nuestro" (paquete) variables que no puedes usar con "mi" (local) variables
Salida:
Esto no funcionará si cambia 'nuestro' a 'mi'.
fuente
perl -e "my $foo = 'bar'; print $foo; ${foo} = 'baz'; pr int $foo"
salida:barbaz
perl -e "my $foo = 'bar'; print $foo; ${"foo"} = 'baz'; print $foo"
salida:barbaz
perl -e "my $foo = 'bar'; print $foo; ${\"foo\"} = 'baz'; print $foo"
salida:barbar
así que en mis pruebas caí en la misma trampa. $ {foo} es lo mismo que $ foo, los corchetes son útiles al interpolar. $ {"foo"} es en realidad una búsqueda de $ main :: {} que es la tabla de símbolos principal, ya que solo contiene variables de ámbito de paquete.perl -e "package test; our $foo = 'bar'; print $foo; ${\"foo\"} = 'baz'; print $foo"
trabajo sensible al paquete , ya que en este contexto $ {"foo"} ahora es igual a $ {"test :: foo"}. Of Symbol Tables and Globs tiene algo de información, al igual que el libro de programación Advanced Perl. Perdón por mi error anterior.Producirá esto:
En caso de usar "use estricto" obtendrá este error al intentar ejecutar el script:
fuente
Solo intenta usar el siguiente programa:
fuente
fuente
our
ymy
diferentes? ¿Cómo lo muestra este ejemplo?Pensemos qué es realmente un intérprete: es un código que almacena valores en la memoria y permite que las instrucciones en un programa que interpreta accedan a esos valores por sus nombres, que se especifican dentro de estas instrucciones. Entonces, el gran trabajo de un intérprete es dar forma a las reglas de cómo debemos usar los nombres en esas instrucciones para acceder a los valores que almacena el intérprete.
Al encontrar "my", el intérprete crea una variable léxica: un valor con nombre al que el intérprete puede acceder solo mientras ejecuta un bloque, y solo desde ese bloque sintáctico. Al encontrar "nuestro", el intérprete crea un alias léxico de una variable de paquete: vincula un nombre, que el intérprete debe procesar a partir de ese momento como el nombre de una variable léxica, hasta que el bloque haya finalizado, con el valor del paquete variable con el mismo nombre.
El efecto es que puede pretender que está utilizando una variable léxica y omitir las reglas de 'uso estricto' en la calificación completa de las variables del paquete. Como el intérprete crea automáticamente las variables del paquete cuando se usan por primera vez, el efecto secundario del uso de "nuestro" también puede ser que el intérprete cree también una variable del paquete. En este caso, se crean dos cosas: una variable de paquete, a la que el intérprete puede acceder desde cualquier lugar, siempre que esté debidamente designada como solicitada por 'use estricto' (antepuesto con el nombre de su paquete y dos puntos), y su alias léxico.
Fuentes:
fuente