Domanda

Esiste un modo per utilizzare una costante come chiave hash?

Per esempio:

use constant X => 1;

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

Il codice sopra creerà un hash con "X" come chiave e non 1 come chiave.Invece, voglio usare il valore della costante X come chiave.

È stato utile?

Soluzione

use constant in realtà crea subroutine costanti.

Per fare quello che vuoi, devi chiamare esplicitamente il sub:

use constant X => 1;

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

O

use constant X => 1;

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

Altri suggerimenti

Un'altra opzione è non utilizzare il pragma use Constant e passare a Readonly secondo le raccomandazioni contenute nelle Perl Best Practices di Damian Conway.

Sono passato qualche tempo fa dopo aver realizzato che i riferimenti hash costanti sono solo un riferimento costante all'hash, ma non fanno nulla per i dati all'interno dell'hash.

La sintassi di sola lettura crea variabili "dall'aspetto normale", ma in realtà imporrà la costanza o la sola lettura.Puoi usarlo come faresti con qualsiasi altra variabile come chiave.


use Readonly;

Readonly my $CONSTANT => 'Some value';

$hash{$CONSTANT} = 1;

Il tuo problema è che => è una virgola magica che cita automaticamente la parola che la precede.Quindi quello che hai scritto è equivalente a ('X', 'X').

Il modo più semplice è usare semplicemente una virgola:

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

Oppure puoi aggiungere vari segni di punteggiatura in modo da non avere più una semplice parola davanti a =>:

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

Utilizzo $hash{CONSTANT()} O $hash{+CONSTANT} per evitare che il meccanismo delle citazioni bareword entri in funzione.

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

La maggior parte delle altre persone hanno risposto bene alla tua domanda.Presi insieme, questi creano una spiegazione molto completa del problema e le soluzioni alternative consigliate.Il problema è che il pragma Perl "usa costante" crea in realtà una subroutine nel pacchetto corrente il cui nome è il primo argomento del pragma e il cui valore è l'ultimo.

In Perl, una volta dichiarata una subroutine, può essere chiamata senza parentesi.

Comprendendo che le "costanti" sono semplicemente subroutine, puoi capire perché non sono interpolate nelle stringhe e perché l'operatore "virgola grassa" "=>" che cita l'argomento di sinistra pensa che tu gli abbia passato una stringa (prova altri programmi compilati -in funzioni come time() e keys() a volte con la virgola grassa per un divertimento extra).

Fortunatamente, puoi invocare la costante usando la punteggiatura esplicita come le parentesi o il sigillo della e commerciale.

Ho però una domanda per te:perché stai usando costanti per le chiavi hash?

Mi vengono in mente alcuni scenari che potrebbero portarti in questa direzione:

  1. Vuoi il controllo su quali chiavi possono essere presenti nell'hash.

  2. Vuoi astrarre il nome delle chiavi nel caso in cui queste cambino in seguito

Nel caso del numero 1, le costanti probabilmente non salveranno il tuo hash.Prendi invece in considerazione la creazione di una classe che abbia setter e getter pubblici che popolano un hash visibile solo all'oggetto.Questa è una soluzione molto diversa dal Perl, ma molto semplice da realizzare.

Nel caso del numero 2, continuerei a sostenere fortemente una Classe.Se l'accesso all'hash è regolato tramite un'interfaccia ben definita, solo l'implementatore della classe è responsabile di ottenere i nomi corretti delle chiavi hash.In tal caso, non suggerirei affatto di utilizzare le costanti.

Spero che questo ti aiuti e grazie per il tuo tempo.

IL use constant pragma crea una subroutine prototipata per non accettare argomenti.Mentre esso sembra come una costante in stile C, è in realtà una subroutine che restituisce un valore costante.

IL => (virgola grassa) cita automaticamente l'operando sinistro se è una bareword, così come la notazione $hash{key}.

Se il tuo utilizzo del nome costante sembra una bareword, i meccanismi di virgolette entreranno in azione e otterrai il suo nome come chiave invece del suo valore.Per evitare ciò, modifica l'utilizzo in modo che non sia una bareword.Per esempio:

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

Negli inizializzatori, potresti anche usare la virgola semplice invece:

%hash = (X, 1);

=> L'operatore interpreta il suo lato sinistro come una "stringa", come fa qw().

Prova a utilizzare

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

Un modo è incapsulare X come (X):

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

Un'altra opzione è eliminare '=>' e utilizzare invece ',':

my %x ( X, 1 );

Commenta @shelfoo (la reputazione non è ancora abbastanza alta per aggiungere commenti direttamente lì!)

Totalmente d'accordo sulle migliori pratiche di Perl di Damian Conway...è una lettura altamente consigliata.

Comunque ti invitiamo a leggere Commento sulle raccomandazioni del modulo PBP che è un'utile "errata" se prevedi di utilizzare PBP per una guida di stile interna.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top