Existe alguma maneira de usar uma "constante" como chave hash em Perl?

Existe alguma maneira de usar uma constante como uma chave 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 como chave. Considerando que, eu quero usar o valor da constante X como chave.

0

9 Respostas

=> operator interprets its left side as a "string", the way qw() does.

Tente usar

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

Comente @shelfoo (reputação não alta o suficiente para adicionar comentários diretamente lá ainda!)

Concordo totalmente sobre Perl Best Practices por Damian Conway ... sua leitura altamente recomendada.

No entanto, leia Comentário de Recomendação do Módulo PBP que é uma "errata" útil se você planeje usar PBP para um guia de estilo interno.

0
adicionado
Obrigado por isso, bom saber. Eu saí do meu show perl, então eu provavelmente não vou usá-lo em casa, mas eu encaminhei esse link para uma das pessoas com quem eu costumava trabalhar.
adicionado o autor shelfoo, fonte

Your problem is that => is a magic comma that automatically quotes the word in front of it. So what you wrote is equivalent to ('X', 'X').

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

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

Or, you can add various punctuation so that you no longer have a simple word in front of the =>:

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

O pragma use constant cria uma sub-rotina criada para não usar argumentos. Embora pareça uma constante no estilo C, é realmente uma sub-rotina que retorna um valor constante.

The => (fat comma) automatically quotes left operand if its a bareword, as does the $hash{key} notation.

Se o seu uso do nome da constante se parecer com uma bareword, os mecanismos de cotação serão acionados e você receberá seu nome como a chave em vez de seu valor. Para evitar isso, altere o uso para que não seja uma bareword. Por exemplo:

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

Nos inicializadores, você também pode usar a vírgula comum:

%hash = (X, 1);
0
adicionado

Use o $ hash {CONSTANT ()} ou o $ hash {+ CONSTANT} para evitar que o mecanismo de citação da palavra barque seja acionado.

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

0
adicionado

use constant actually makes constant subroutines.

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');
0
adicionado

Uma maneira é encapsular X como (X):

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

Another option is to do away with '=>' and use ',' instead:

my %x ( X, 1 );
0
adicionado

Outra opção é não usar o pragma constante de uso e inverter para Readonly como por recomendações no Perl Best Practices por Damian Conway.

Eu mudei um tempo atrás depois de perceber que os hashs constantes são apenas uma referência constante ao hash, mas não fazem nada sobre os dados dentro do hash.

A sintaxe readonly cria variáveis ​​de "aparência normal", mas na verdade reforça a constante ou o readonlyness. Você pode usá-lo como faria com qualquer outra variável como chave.


use Readonly;

Readonly my $CONSTANT => 'Some value';

$hash{$CONSTANT} = 1;

0
adicionado
Não é um módulo Core.
adicionado o autor ceving, fonte

A maioria das outras pessoas respondeu bem a sua pergunta. Juntos, eles criam uma explicação completa do problema e recomendam soluções alternativas. A questão é que o pragma Perl "use constante" realmente cria uma sub-rotina no seu pacote atual cujo nome é o primeiro argumento do pragma e cujo valor é o último.

Em Perl, quando uma sub-rotina é declarada, pode ser chamada sem parênteses.

Understanding that "constants" are simply subroutines, you can see why they are not interpolated in strings and why the "fat comma" operator "=>" which quotes the left-hand argument thinks you've handed it a string (try other built-in functions like time() and keys() sometime with the fat comma for extra fun).

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

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

Eu posso pensar em alguns cenários que podem levá-lo nessa direção:

  1. Você quer controlar quais chaves podem estar no hash.

  2. Você deseja abstrair o nome das chaves caso elas sejam alteradas posteriormente

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

No caso do número 2, eu ainda defendo fortemente uma classe. Se o acesso ao hash é regulado por meio de uma interface bem definida, somente o implementador da classe é responsável por acertar os nomes das chaves de hash. Nesse caso, eu não sugeriria usar constantes.

Espero que isso ajude e obrigado pelo seu tempo.

0
adicionado