Pregunta

¿Hay alguna forma de utilizar una constante como 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.Mientras que quiero usar el valor de la constante X como clave.

¿Fue útil?

Solución

use constant en realidad hace subrutinas constantes.

Para hacer lo que quieres, necesitas llamar explícitamente al sub:

use constant X => 1;

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

o

use constant X => 1;

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

Otros consejos

Otra opción es no utilizar el uso de pragma constante y pasar a Solo lectura según las recomendaciones de las Mejores prácticas de Perl de Damian Conway.

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

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


use Readonly;

Readonly my $CONSTANT => 'Some value';

$hash{$CONSTANT} = 1;

Tu problema es que => es una coma mágica que automáticamente cita la palabra que tiene delante.Entonces lo que escribiste es equivalente a ('X', 'X').

La forma más sencilla es utilizar una coma:

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

O puede agregar varios signos de puntuación para que ya no tenga una palabra simple delante de =>:

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

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

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

La mayoría de las otras personas han respondido bien a tu pregunta.En conjunto, estos crean una explicación muy completa del problema y las soluciones recomendadas.El problema es que el "uso constante" del pragma de Perl 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 declarada una subrutina, se puede llamar sin paréntesis.

Al comprender que las "constantes" son simplemente subrutinas, puede ver por qué no se interpolan en cadenas y por qué el operador de "coma gruesa" "=>" que cita el argumento de la izquierda cree que le ha entregado una cadena (pruebe con otros construidos). -in funciones como time() ykeys() en algún momento con la coma gruesa para mayor diversión).

Afortunadamente, puedes invocar la constante usando puntuación explícita como paréntesis o el signo comercial.

Sin embargo, tengo una pregunta para ti:¿Por qué utilizas constantes para las claves hash?

Puedo pensar en algunos escenarios que podrían llevarlo en esta dirección:

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

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

En el caso del número 1, las constantes probablemente no guardarán su hash.En su lugar, considere crear una clase que tenga definidores y captadores públicos que completen un hash visible solo para el objeto.Esta es una solución muy diferente a Perl, pero muy fácil de hacer.

En el caso del número 2, todavía recomendaría firmemente una Clase.Si el acceso al hash se regula a través de una interfaz bien definida, sólo el implementador de la clase es responsable de obtener los nombres correctos de las claves hash.En cuyo caso, no sugeriría utilizar constantes en absoluto.

Espero que esto ayude y gracias por tu tiempo.

El use constant pragma crea un prototipo de subrutina que no acepta argumentos.mientras aspecto Al igual que una constante de estilo C, en realidad es una subrutina que devuelve un valor constante.

El => (coma gruesa) automáticamente cita el operando izquierdo si es una palabra simple, al igual que la notación $hash{key}.

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

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

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

%hash = (X, 1);

=> El operador interpreta su lado izquierdo como una "cadena", como lo hace qw().

Intenta usar

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

Una forma es encapsular X como (X):

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

Otra opción es eliminar '=>' y usar ',' en su lugar:

my %x ( X, 1 );

Comente @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 por favor lea Comentario de recomendación del módulo PBP lo cual es una "errata" útil si planea utilizar PBP para una guía de estilo interna.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top