Quando você deve usar uma variável de pacote contra uma variável lexical (e qual é a diferença)?

StackOverflow https://stackoverflow.com/questions/1019617

Pergunta

Eu estou olhando para algum código Perl mais velho na Perl Monks descobrir programação com Win32 :: OLE e MS Word. Espalhadas por todo o código são variáveis ??com nomes como $ MS :: Palavra e similares, sem uma ' minha ' incluído em sua declaração. Depois de ler um pouco no Google, eu entendo que estes são chamados de 'variáveis ??de pacote' Versus 'variáveis ??lexicais' declarado usando minha .

A minha primeira pergunta é ' Quais são pacote variáveis ??bom? '. I (acho) Eu entendo o que variáveis ??lexicais são, mas eu não entendo o propósito de variáveis ??de pacote ou como seus uso difere lexicals, por isso a minha segunda pergunta seria: ' Qual é a diferença entre as variáveis ??lexicais e pacote ? '

Foi útil?

Solução

variável de pacote vive uma em uma tabela de símbolos, assim dado o seu nome, é possível ler ou modificá-lo de qualquer outro pacote ou extensão. O escopo de uma variável lexical é determinada pelo texto do programa. A seção "variáveis ??privadas através do meu ()" em o perlsub manpage dá mais detalhes sobre a definição de lexicals.

Say, temos o seguinte MyModule.pm:

package MyModule;

# these are package variables
our $Name;
$MyModule::calls = "I do not think it means what you think it means.";

# this is a lexical variable
my $calls = 0;

sub say_hello {
  ++$calls;

  print "Hello, $Name!\n";
}

sub num_greetings {
  $calls;
}

1;

Observe que ele contém uma $calls pacote e um $calls lexical. Qualquer um pode chegar ao primeiro, mas os controles módulo de acesso a este último:

#! /usr/bin/perl

use warnings;
use strict;

use MyModule;

foreach my $name (qw/ Larry Curly Moe Shemp /) {
  $MyModule::Name = $name;
  MyModule::say_hello;
}

print MyModule::num_greetings, "\n";

print "calls = $MyModule::calls\n";

A saída do programa é

Hello, Larry!
Hello, Curly!
Hello, Moe!
Hello, Shemp!
4
calls = I do not think it means what you think it means.

Como você pode ver, variáveis ??de pacote são globais, assim todas as armadilhas usuais e conselhos contra aplica. A menos que o acesso explicitamente previsto, é impossível para o código fora do pacote MyModule para acessar seus $calls lexical.

A regra de ouro é que você quase sempre quer usar lexicals. Perl Best Practices por Damian Conway é direta: " Nunca faça variáveis ??parte da interface de um módulo "(ênfase no original).

Outras dicas

Você deve ler lidar com Scoping por MJD.

perldoc perlmod também seria leitura útil.

O código é fora deste mundo feio. Ele pisoteia todos os tipos de namespaces sem uma preocupação em todo o mundo só porque o autor parece pensar $ autor :: e-mail é legal.

A melhor maneira seria usar um hash:

my %author = (
   email => 'author@example.com',
   ...
);

Trampolim todo tabela de símbolos não é necessário.

Eu tenho alguns exemplos Win32::OLE: http://www.unur.com/comp/ que há obras de arte, mas eu acredito que são melhorias sobre este modelo. Veja também por que o número de páginas em um diferente documento do Word em Perl e VBA do Word?

eu vou reclamar um pouco :

@pgm::runtime_args = @ARGV ;

Então, nós desistir da matriz @ARGV padrão para pisar o namespace pgm. Não só isso, cada programador Perl sabe o que @ARGV é. Em qualquer caso, @pgm::runtime_args não é usada novamente no script.

$pgm::maxargs = $#pgm::runtime_args + 1 ;

É claro @pgm::runtime_args no contexto escalar nos daria o número de elementos do array. Eu não tenho idéia por que $pgm::maxargs pode ser necessária, mas se fosse, então esta linha deveria ter sido:

$pgm::maxargs = @pgm::runtime_args;

Eu não vou citar mais deste material. Eu acho que isso é o que acontece quando os programadores Cobol tentar escrever Perl.

$program::copyright = "Copyright (c) 02002 - Kenneth Tomiak : All rights reserved.";

Estou feliz que ele alocado cinco dígitos para o ano. Ya nunca sabe!

PS: Eu acredito que meus trechos constituem uso justo

.

variáveis ??de pacote são variáveis ??globais; eles são visíveis em todos os lugares em todo o programa (até mesmo outros módulos). Eles são úteis quando você quer ou precisa que o nível de visibilidade e / ou influência externa. Por exemplo, o texto :: módulo Enrole os usa para permitir um único ponto de configuração para o número de colunas em que para quebrar o texto. Futhermore, variáveis ??de pacote permitem que você use algo chamado "escopo dinâmico" - mas isso é um conceito um tanto avançada e leve esotérico

.

Para a sua segunda questão, consulte Qual é a diferença entre a minha e nossa em Perl?

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