Pergunta

Eu estou vendo ambos usados ??neste script Eu estou tentando depurar e literatura simplesmente não é clara. Alguém pode desmistificar essa para mim?

Foi útil?

Solução

Dinâmica de escopo. É um conceito puro. Muitas pessoas não usá-lo, ou compreendê-lo.

Basicamente pensar my como a criação e ancorando uma variável para um bloco de {}, A.K.A. escopo.

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

Assim, uma variável my é o que você está acostumado. enquanto que com a dinâmica de escopo $ var pode ser declarada em qualquer lugar e em qualquer lugar usado. Assim, com local você basicamente suspender o uso dessa variável global, e usar um "valor local" para trabalhar com ele. Então local cria um escopo temporário para uma variável temporária.

$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 ++;
}

Isso deve imprimir:

4
10
11
4

Outras dicas

A resposta curta é que as marcas de my uma variável como privado em um escopo lexical e marcas local uma variável como privado em um escopo dinâmico.

É mais fácil de entender my, uma vez que cria uma variável local no sentido usual. Existe uma nova variável criada e é acessível apenas dentro do bloco lexical juntando, que normalmente é marcada por chaves. Há algumas exceções à regra encaracolado-chave, tais como:

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

Mas isso é apenas Perl fazendo o que você quer dizer. Normalmente você tem algo como isto:

sub Foo {
   my $x = shift;

   print "$x\n";
}

Nesse caso, $x é privado para a sub-rotina e seu escopo é delimitada pelas chaves. A coisa a notar, e este é o contraste com local, é que o escopo de uma variável my é definido com relação ao seu código como está escrito no arquivo. É um fenômeno de tempo de compilação.

Para entender local, você precisa pensar em termos de pilha de chamada do seu programa como ele está sendo executado. Quando uma variável é local, ele é redefinido a partir do ponto em que os executa statement local para tudo abaixo que na pilha, até você voltar a pilha para o chamador do bloco que contém o local.

Isso pode ser confuso no início, assim que considerar o seguinte exemplo.

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

Quando foo é chamado pela primeira vez, ele vê o valor global das $x que é 1. Quando bar é chamado e executado local $x, que redefine o $x global sobre a pilha. Agora, quando foo é chamado de bar, vê o novo valor de 2 para $x. Até agora isso não é muito especial, porque a mesma coisa teria acontecido sem a chamada para local. A magia é que quando bar retornos que sair do escopo dinâmico criado por local $x eo $x mundial anterior volta para o escopo. Assim, para a chamada final de foo, $x é 1.

Você quase sempre quer usar my, uma vez que lhe dá a variável local que você está procurando. Uma vez em uma lua azul, local é realmente útil para fazer coisas legais.

Learning Perl :

Mas local é chamado erroneamente, ou pelo menos enganosamente chamado. Nosso amigo Chip Salzenberg diz que se ele nunca tem a chance de voltar em uma máquina do tempo para 1986 e dar Larry um conselho, ele diria Larry para chamar local pelo nome de "save" em vez. [14] Isso porque locais realmente vai salvar o valor da variável global doado, por isso vai mais tarde ser automaticamente restaurado para a variável global. (É isso mesmo: os chamados variáveis ??"locais" são realmente globais!) Isto salvar e restauração mecanismo é o mesmo que já vimos duas vezes agora, na variável de um loop foreach controle e na @_ matriz de parâmetros de sub-rotinas.

Assim, local salva o valor atual de uma variável global e, em seguida, configurá-lo para alguma forma de valor vazio. Muitas vezes você vai vê-lo usado para ingerir um arquivo inteiro, em vez de levando apenas uma linha:

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

Chamando local $/ define o separador de registro de entrada (o valor que Perl pára de ler uma "linha" at) para um valor vazio, fazendo com que o operador nave espacial para ler o arquivo inteiro, para que ele nunca atinge o separador de registro de entrada.

Eu não posso acreditar que ninguém tenha ligado a tratados exaustivos Mark Jason Dominus’ sobre o assunto:

http://perldoc.perl.org/perlsub .html # privados-Variáveis-via-my ()

Ao contrário de variáveis ??dinâmicas criadas por o operador local, variáveis ??lexicais declarou com a minha estão totalmente escondida do mundo exterior, incluindo qualquer subrotinas. Isso é verdade se é a mesma sub-rotina chamada de em si ou em outro lugar - cada chamada recebe sua própria cópia.

http://perldoc.perl.org/perlsub .html # temporários-Valores-via-local ()

A modifica locais suas variáveis ??listadas para ser "local" para o bloco envolvendo, eval, ou ARQUIVO --e a qualquer sub-rotina chamada a partir desse quadra. A apenas locais dá temporária valores a global (ou seja, pacote) variáveis. Ele não cria um local de variável. Isto é conhecido como dinâmico escopo. escopo lexical é feito com meu, que funciona mais como auto de C declarações.

Eu não acho que isso é de todo claro, além de dizer que por "local para o bloco de inclusão", o que significa é que o valor original é restaurada quando o bloco é encerrado.

Bem Google realmente funciona para você em um presente: http://www.perlmonks.org/? node_id = 94007

A partir do link:

Breve resumo: 'meu' cria um novo variáveis, temporariamente pazes 'locais' o valor de uma variável.

ou seja, 'local' muda temporariamente o valor da variável , mas apenas no âmbito existe em.

Geralmente uso o meu, é mais rápido e não faz nada meio estranho.

De man perlsub:

variáveis ??dinâmicas Ao contrário criados pelo operador local, variáveis ??lexicais declarada com a minha está totalmente escondido do mundo exterior, incluindo quaisquer chamadas de sub-rotinas.

Assim, simplificando, my faz sua variável visível somente onde ele é declarado. local torna visível para baixo a pilha de chamadas também. Normalmente você vai querer usar my vez de local.

Sua confusão é compreensível. escopo lexical é bastante fácil de entender, mas escopo dinâmico é um conceito incomum. A situação é agravada pelos nomes my e local sendo um tanto imprecisa (ou pelo menos intuitiva) por razões históricas.

my declara uma variável lexical - um que é visível a partir do ponto de declaração até o fim do bloco de inclusão (ou arquivo). É completamente independente de quaisquer outras variáveis ??com o mesmo nome no resto do programa. Ele é particular a esse bloco.

local, por outro lado, declara uma mudança temporária para o valor de uma variável global. As extremidades alteração no final do escopo delimitador, mas a variável - ser global -. É em qualquer lugar visível no programa

Como regra geral, o uso my para declarar suas próprias variáveis ??e local para controlar o impacto das mudanças de variáveis ??internas do Perl.

Para uma descrição mais completa ver artigo Mark Jason Dominus' lidar com Scoping .

local é um método mais antigo de localização, dos tempos em Perl só tinham escopo dinâmico. escopo lexical é muito mais natural para o programador e muito mais seguro em muitas situações. meus variáveis ??pertencem ao âmbito (bloco, pacote ou arquivo), no qual eles são declarados.

variáveis ??locais em vez realmente pertencem a um namespace global. Se você se referir a uma variável $ x com local, na verdade você está se referindo a US $ principal :: x, que é uma variável global. Ao contrário do que o próprio nome indica, todos os locais faz é empurrar um novo valor para uma pilha de valores por US $ principal :: x até o final deste bloco, momento em que o valor antigo será restaurado. Esse é um recurso útil em si mesmo, mas não é uma boa maneira de ter variáveis ??locais para uma série de razões (acho que o que acontece quando você tem tópicos! E acho que o que acontece quando você chamar uma rotina que realmente quer usar um global que você ter localizado!). No entanto, foi a única maneira de ter variáveis ??que pareciam variáveis ??locais de volta nos velhos tempos, antes de Perl 5. Nós ainda está preso com ele.

"meus" variáveis ??são visíveis apenas no bloco de código atual. variáveis ??"locais" também são visíveis onde quer que eles eram visíveis antes. Por exemplo, se você disser "my $ x"; e chamar uma sub-função, ele não pode ver essa variável $ x. Mas se você diz "$ local /"; (Como nulo o valor do separador de registro), então você mudar a maneira como a leitura de arquivos funciona em qualquer função que você chama.

Na prática, quase sempre quer "minha", não "local".

Observe o seguinte código e sua saída para entender a diferença.

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;

A saída é:

Name = Abhishek

Name = Abhijeet

Name = Abhinav

exemplo do uso de local para redefinir o delimitador de registro das dinomite é a única vez que eu tenho correu em um monte de programação Perl. Eu vivo em um ambiente de nicho perl [de programação de segurança], mas é realmente um escopo raramente usado na minha experiência.

&s;

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

sub b()
{
    $s++;
}

O script acima impressões 6.

Mas se mudarmos local para minha imprimirá 5.

Esta é a diferença. Simples.

Eu acho que a maneira mais fácil de lembrar que é desta forma. MY cria uma nova variável. LOCAL muda temporariamente o valor de uma variável existente.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top