Eu sei o que my
há em Perl. Ele define uma variável que existe apenas no escopo do bloco em que está definida. O que our
faz?
Como é que our
difere my
?
Ótima pergunta: como our
difere my
e o que our
faz?
Em suma:
Disponível desde o Perl 5, my
é uma maneira de declarar variáveis que não são de pacote, que são:
$package_name::variable
.Por outro lado, our
variáveis são variáveis de pacote e, portanto, automaticamente:
$package_name::variable
.Declarar uma variável com our
permite pré-declarar variáveis para usá-las use strict
sem receber avisos de erro de digitação ou erros em tempo de compilação. Desde o Perl 5.6, ele substituiu o obsoleto use vars
, que tinha apenas escopo de arquivo e não lexicamente como está our
.
Por exemplo, o nome formal e qualificado para a variável $x
inside package main
é $main::x
. Declarar our $x
permite que você use a $x
variável bare sem penalidade (ou seja, sem erro resultante), no escopo da declaração, quando o script usa use strict
or use strict "vars"
. O escopo pode ser um ou dois ou mais pacotes ou um pequeno bloco.
local
não cria variáveis. Ele não se relaciona commy
eour
em tudo.local
faz backup temporário do valor da variável e limpa seu valor atual.our
variáveis não são variáveis de pacote. Eles não têm escopo global, mas variáveis de escopo lexical como asmy
variáveis. Você pode ver que o seguinte programa:package Foo; our $x = 123; package Bar; say $x;
. Se você quiser "declarar" uma variável do pacote, precisará usaruse vars qw( $x );
.our $x;
declara uma variável de escopo lexicamente alias à variável com o mesmo nome no pacote em que aour
compilação foi compilada.Os links PerlMonks e PerlDoc da cartman e Olafur são uma ótima referência - abaixo está minha rachadura em um resumo:
my
as variáveis têm escopo lexicamente dentro de um único bloco definido por{}
ou dentro do mesmo arquivo, se não em{}
s. Eles não são acessíveis a partir de pacotes / sub-rotinas definidas fora do mesmo escopo / bloco lexical.our
as variáveis têm o escopo definido dentro de um pacote / arquivo e acessíveis a partir de qualquer código queuse
ourequire
aquele conflito de nome do pacote / arquivo seja resolvido entre os pacotes, precedendo o espaço de nome apropriado.Para finalizar, as
local
variáveis têm escopo "dinâmico", diferindo dasmy
variáveis, pois também são acessíveis a partir de sub-rotinas chamadas dentro do mesmo bloco.fonte
my
variáveis têm escopo lexicamente [...] dentro do mesmo arquivo, se não em{}
s". Isso foi útil para mim, obrigado.Um exemplo:
fonte
Lidar com o escopo é uma boa visão geral das regras de escopo do Perl. É velho o suficiente para
our
não ser discutido no corpo do texto. É abordada na seção Notas no final.O artigo fala sobre variáveis de pacote e escopo dinâmico e como isso difere de variáveis lexicais e escopo lexical.
fonte
my
é usado para variáveis locais, enquanto queour
é usado para variáveis globais.Leia mais em Variable Scoping in Perl: the basic .
fonte
${^Potato}
é global. Refere-se à mesma variável, independentemente de onde você a usa.Eu já conheci algumas armadilhas sobre declarações lexicais no Perl que me atrapalharam, que também estão relacionadas a essa pergunta, então apenas adiciono meu resumo aqui:
1. Definição ou declaração?
A saída é
var: 42
. No entanto, não sabemos selocal $var = 42;
é uma definição ou declaração. Mas e quanto a isso:O segundo programa lançará um erro:
$var
não está definido, o que significa quelocal $var;
é apenas uma declaração! Antes de usarlocal
para declarar uma variável, verifique se ela está definida como uma variável global anteriormente.Mas por que isso não irá falhar?
A saída é:
var: 42
.Isso porque
$a
, além de$b
, é uma variável global predefinida no Perl. Lembre-se da função de classificação ?2. Lexical ou global?
Eu era um programador C antes de começar a usar o Perl, então o conceito de variáveis lexicais e globais parece direto para mim: apenas corresponde a variáveis automáticas e externas em C. Mas há pequenas diferenças:
Em C, uma variável externa é uma variável definida fora de qualquer bloco de função. Por outro lado, uma variável automática é uma variável definida dentro de um bloco de funções. Como isso:
Enquanto em Perl, as coisas são sutis:
A saída é
var: 42
.$var
é uma variável global, mesmo que esteja definida em um bloco de funções! Na verdade, em Perl, qualquer variável é declarada como global por padrão.A lição é sempre adicionar
use strict; use warnings;
no início de um programa Perl, o que forçará o programador a declarar explicitamente a variável lexical, para que não fiquemos confusos com alguns erros tomados como garantidos.fonte
O perldoc tem uma boa definição de nossa.
fonte
Isso está apenas um pouco relacionado à questão, mas eu acabei de descobrir um bit obscuro (para mim) de sintaxe perl que você pode usar com variáveis "our" (package) que você não pode usar com "my" (local) variáveis.
Resultado:
Isso não funcionará se você alterar 'nosso' para 'meu'.
fonte
perl -e "my $foo = 'bar'; print $foo; ${foo} = 'baz'; pr int $foo"
output:barbaz
perl -e "my $foo = 'bar'; print $foo; ${"foo"} = 'baz'; print $foo"
output:barbaz
perl -e "my $foo = 'bar'; print $foo; ${\"foo\"} = 'baz'; print $foo"
output:barbar
Então, em meus testes, caí na mesma armadilha. $ {foo} é o mesmo que $ foo, os colchetes são úteis ao interpolar. $ {"foo"} é, na verdade, uma consulta a $ main :: {}, que é a tabela principal de símbolos, pois contém apenas variáveis com escopo definido no pacote.perl -e "package test; our $foo = 'bar'; print $foo; ${\"foo\"} = 'baz'; print $foo"
, pois neste contexto $ {"foo"} agora é igual a $ {"test :: foo"}. Of Symbol Tables and Globs tem algumas informações, assim como o livro de programação Advanced Perl. Desculpe pelo meu erro anterior.Saída isso:
No caso de usar "use strict", ocorrerá esta falha ao tentar executar o script:
fonte
Apenas tente usar o seguinte programa:
fonte
fonte
our
emy
diferentes? Como este exemplo mostra isso?Vamos pensar o que realmente é um intérprete: é um pedaço de código que armazena valores na memória e permite que as instruções em um programa que ele interpreta acessem esses valores por seus nomes, especificados nessas instruções. Portanto, o grande trabalho de um intérprete é moldar as regras de como devemos usar os nomes nessas instruções para acessar os valores que o intérprete armazena.
Ao encontrar "meu", o intérprete cria uma variável lexical: um valor nomeado que o intérprete pode acessar apenas enquanto executa um bloco e somente dentro desse bloco sintático. Ao encontrar "our", o intérprete cria um alias lexical de uma variável do pacote: vincula um nome, que o intérprete deve processar a partir de então como o nome de uma variável lexical, até o término do bloco, ao valor do pacote variável com o mesmo nome.
O efeito é que você pode fingir que está usando uma variável lexical e ignorar as regras de 'use strict' na qualificação completa das variáveis de pacote. Como o intérprete cria automaticamente variáveis de pacote quando elas são usadas pela primeira vez, o efeito colateral de usar "our" também pode ser que o intérprete crie também uma variável de pacote. Nesse caso, duas coisas são criadas: uma variável de pacote, que o intérprete pode acessar de qualquer lugar, desde que seja adequadamente designada conforme solicitado por 'use strict' (precedido com o nome de seu pacote e dois pontos) e seu alias lexical.
Fontes:
fonte