Quando você deve usar uma variável de pacote contra uma variável lexical (e qual é a diferença)?
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 ? '
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?