Pergunta

Existe alguma maneira de usar uma constante como uma chave de hash?

Por exemplo:

use constant X => 1;

my %x = (X => 'X');

O código acima irá criar um hash com "X" como chave e não 1 na chave. Considerando que, eu quero usar o valor de X constante como chave.

Foi útil?

Solução

use constant realmente faz sub-rotinas constantes.

Para fazer o que você quer, você precisa chamar explicitamente o sub:

use constant X => 1;

my %x = ( &X => 'X');

ou

use constant X => 1;

my %x = ( X() => 'X');

Outras dicas

Outra opção é não usar o pragma uso constante e flip para somente leitura conforme recomendações das Perl Best Practices por Damian Conway.

Troquei um tempo atrás depois de perceber que constante de hash ref do são apenas uma referência constante para o hash, mas não fazer nada sobre os dados dentro do hash.

A sintaxe readonly cria variáveis ??"normais futuro", mas vai realmente cumprir a constantness ou readonlyness. Você pode usá-lo como faria com qualquer outra variável como uma chave.


use Readonly;

Readonly my $CONSTANT => 'Some value';

$hash{$CONSTANT} = 1;

Seu problema é que => é uma vírgula mágica que cita automaticamente a palavra na frente dele. Então o que você escreveu é equivalente a ( 'X', 'X').

A maneira mais simples é usar apenas uma vírgula:

my %x = (X, 'X');

Ou, você pode adicionar vários pontuação de modo que você já não tem uma palavra simples na frente do =>:

my %x = ( X() => 'X' );
my %x = ( &X => 'X' );

Use $hash{CONSTANT()} ou $hash{+CONSTANT} para evitar a bareword mecanismo citando chutando.

De: http://perldoc.perl.org/constant.html

A maioria das outras pessoas têm respondido à sua pergunta também. Tomados em conjunto, estes criam uma explicação muito completa do problema e soluções alternativas recomendadas. A questão é que o Perl pragma "uso constante" realmente cria uma sub-rotina em seu pacote atual cujo nome é o primeiro argumento da Pragma e cujo valor é o último.

Em Perl, uma vez que uma sub-rotina é declarado, ele pode ser chamado sem parênteses.

entendimento de que "constantes" são simplesmente sub-rotinas, você pode ver por que eles não são interpolados em cordas e por que o operador "vírgula gordura" "=>", que cita o argumento do lado esquerdo pensa que você entregou uma string ( tente outra built-in funções como time () e as teclas () em algum momento com a vírgula gordura para o divertimento extra).

Felizmente, você pode invocar a constante o uso de pontuação explícita como parens ou o sigilo comercial.

No entanto, eu tenho uma pergunta para você: por que você está usando constantes para chaves de hash em tudo?

Não consigo pensar em alguns cenários que podem levar você nessa direção:

  1. Você quer controle sobre quais chaves podem estar no hash.

  2. Você quer resumo o nome das chaves em caso estes mudar mais tarde

No caso do número 1, constantes provavelmente não vai salvar o seu hash. Em vez disso, considere a criação de uma classe que tem setters públicos e getters que povoam um hash visível apenas para o objeto. Isto é muito un-Perl como solução, mas muito fácil de fazer.

No caso do número 2, eu ainda defendo fortemente para uma classe. Se o acesso ao hash é regulada através de uma interface definida pelo bem, apenas o implementador da classe é responsável por obter os nomes-chave de hash direita. Nesse caso, eu não iria sugerir o uso de constantes em tudo.

Espero que isso ajude e obrigado pelo seu tempo.

O pragma use constant cria uma sub-rotina protótipo para tomar sem argumentos. Embora aparência como uma constante de estilo C, é realmente uma sub-rotina que retorna um valor constante.

O => (vírgula gordura) cita automaticamente operando à esquerda se o seu bareword, assim como o $ de hash {key} notação.

Se o seu uso dos olhares nome da constante como um bareword, os mecanismos citando vai chutar e você vai ter o seu nome como a chave em vez de seu valor. Para evitar isso, alterar o uso para que ele não é um bareword. Por exemplo:

use constant X => 1;
%hash = (X() => 1);
%hash = (+X => 1);
$hash{X()} = 1;
$hash{+X} = 1;

Em initializers, você também pode usar a vírgula simples em vez disso:

%hash = (X, 1);

=> operador interpreta seu lado esquerdo como um "string", a maneira qw () faz.

Tente usar

my %x = ( X, 'X');

Uma maneira é para encapsular X como (X):

my %x ( (X) => 1 );

Outra opção é para acabar com '=>' e utilização '' em vez disso:

my %x ( X, 1 );

Comentário @shelfoo (reputação não é alta o suficiente para adicionar comentário diretamente ainda lá!)

Totalmente de acordo sobre Perl Best Practices por Damian Conway ... sua leitura altamente recomendável.

No entanto, por favor leia PBP Módulo Recomendação Comentário que é uma "errata útil "Se você pretende usar o PBP para um guia de estilo in-house.

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