¿Hay alguna forma de usar una "constante" como tecla hash en Perl?

¿Hay alguna forma de usar una constante como una clave hash?

Por ejemplo:

use constant X => 1;

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

El código anterior creará un hash con "X" como clave y no 1 como clave. Considerando que, quiero usar el valor de la constante X como clave.

0

9 Respuestas

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

Intenta usar

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

Comenta @shelfoo (¡la reputación no es lo suficientemente alta como para agregar comentarios directamente allí todavía!)

Totalmente de acuerdo con las mejores prácticas de Perl por Damian Conway ... es una lectura muy recomendable.

Sin embargo, lea Comentario de recomendación del módulo PBP , que es una "errata" útil si planea usar PBP para una guía de estilo interna.

0
agregado
Gracias por eso, es bueno saberlo. Pasé de mi trabajo de perl, así que probablemente no lo use en otro lugar que no sea en casa, pero reenví el enlace a una de las personas con las que solía trabajar.
agregado el autor shelfoo, fuente

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').

La forma más sencilla es usar una coma:

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
agregado

El use constant pragma crea una subrutina prototipada para no tomar argumentos. Si bien se ve como una constante de estilo C, en realidad es una subrutina que devuelve un valor constante.

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

Si su uso del nombre de la constante parece una palabra clave, los mecanismos de cotización aparecerán y obtendrá su nombre como la clave en lugar de su valor. Para evitar esto, cambie el uso para que no sea una palabra sencilla. Por ejemplo:

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

En inicializadores, también puedes usar la coma simple:

%hash = (X, 1);
0
agregado

Utilice $ hash {CONSTANT ()} o $ hash {+ CONSTANT} para evitar que el mecanismo de cotización de palabras simples se active.

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

0
agregado

use constant actually makes constant subroutines.

Para hacer lo que desea, debe llamar explícitamente el subtítulo:

use constant X => 1;

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

o

use constant X => 1;

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

Una forma es encapsular X como (X):

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

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

my %x ( X, 1 );
0
agregado

Otra opción es no utilizar el pragma constante de uso y voltear a solo lectura según las recomendaciones de las mejores prácticas de Perl por Damian Conway.

Cambié hace un tiempo después de darme cuenta de que las constantes referencias hash son solo una referencia constante al hash, pero no hagas nada con los datos dentro del hash.

La sintaxis de solo lectura crea variables de "aspecto normal", pero en realidad aplicará la constancia o la capacidad de lectura. Puede usarlo como lo haría con cualquier otra variable como una clave.


use Readonly;

Readonly my $CONSTANT => 'Some value';

$hash{$CONSTANT} = 1;

0
agregado
No es un módulo Core.
agregado el autor ceving, fuente

La mayoría de las otras personas han respondido bien tu pregunta. En conjunto, estos crean una explicación muy completa del problema y soluciones alternativas recomendadas. El problema es que Perl pragma "use constant" realmente crea una subrutina en su paquete actual, cuyo nombre es el primer argumento del pragma y cuyo valor es el último.

En Perl, una vez que se declara una subrutina, se puede invocar sin parens.

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).

Afortunadamente, puede invocar la constante usando signos de puntuación explícitos, como parens o el signo ampersand.

Sin embargo, tengo una pregunta para ti: ¿por qué estás usando constantes para las teclas hash en absoluto?

Puedo pensar en algunos escenarios que pueden llevarte en esta dirección:

  1. Desea controlar qué claves pueden estar en el hash.

  2. Desea abstraer el nombre de las claves en caso de que cambien más tarde

En el caso del número 1, las constantes probablemente no guarden su hash. En su lugar, considere la creación de una clase que tenga adaptadores y obtentores públicos que llenen un hash visible solo para el objeto. Esta es una solución muy poco similar a Perl, pero muy fácil de hacer.

En el caso del número 2, aún abogo fuertemente por una clase. Si el acceso al hash está regulado a través de una interfaz bien definida, solo el implementador de la clase es responsable de obtener los nombres de la clave hash correctamente. En ese caso, no recomendaría usar constantes en absoluto.

Espero que esto ayude y gracias por tu tiempo.

0
agregado