Există vreo modalitate de a utiliza o "constantă" ca cheie de tip hash în Perl?

Există vreo modalitate de a folosi o constantă ca o cheie hash?

De exemplu:

use constant X => 1;

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

Codul de mai sus va crea un hash cu "X" ca cheie și nu 1 ca cheie. În timp ce vreau să folosesc valoarea constantă X ca cheie.

0

9 răspunsuri

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

Încercați să utilizați

my %x = ( X, 'X');
0
adăugat

Comentariu @shelfoo (reputația nu este suficient de mare pentru a adăuga un comentariu direct acolo încă!)

Sunt total de acord cu Perl Best Practices de Damian Conway ... lectura foarte recomandată.

Cu toate acestea, vă rugăm să citiți Comentariul recomandării modulului PBP care este o "errată" utilă dacă intenționați să folosiți PBP pentru un ghid de stil interior.

0
adăugat
Mulțumesc pentru asta, bine să știți. M-am mutat de la concertul meu perl, așa că probabil nu o voi mai folosi decât acasă, dar am trimis această legătură cu unul dintre oamenii cu care lucram.
adăugat autor shelfoo, sursa

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

Cea mai simplă cale este să folosiți o virgulă:

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
adăugat

Pragma use constant creează un prototip subrutină pentru a nu lua argumente. În timp ce arată ca o constantă în stilul C, este într-adevăr o subrutină care returnează o valoare constantă.

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

Dacă folosirea numelui constante arata ca un cuvânt cheie, mecanismele de citare vor da naștere și veți obține numele în calitate de cheie în locul valorii sale. Pentru a preveni acest lucru, schimbați utilizarea, astfel încât să nu fie un cuvânt cheie. De exemplu:

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

În inițializatori, puteți utiliza și virgula simplă:

%hash = (X, 1);
0
adăugat

Utilizați $ hash {CONSTANT ()} sau $ hash {+ CONSTANT} pentru a împiedica introducerea mecanismului de citare.

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

0
adăugat

use constant actually makes constant subroutines.

Pentru a face ceea ce dsauiți, trebuie să sunați în mod explicit sub:

use constant X => 1;

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

sau

use constant X => 1;

my %x = ( X() => 'X');
0
adăugat

O modalitate este de a încapsula X ca (X):

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

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

my %x ( X, 1 );
0
adăugat

O altă opțiune este să nu folosești pragma constantă și să te întorci la Readonly conform recomandărilor din cele mai bune practici ale lui Damian Conway.

Am trecut un timp în urmă după ce am dat seama că acea constantă hash ref are doar o referință constantă la hash, dar nu face nimic despre datele din hash.

Sintaxa readonly creează variabile "cu aspect normal", dar va aplica de fapt constanța sau readonlyness. Poți să o folosești la fel ca orice altă variabilă ca o cheie.


use Readonly;

Readonly my $CONSTANT => 'Some value';

$hash{$CONSTANT} = 1;

0
adăugat
Nu este un modul Core.
adăugat autor ceving, sursa

Majoritatea celorlalți au răspuns bine la întrebarea dvs. Luate împreună, acestea creează o explicație foarte detaliată a problemei și recomandă soluții. Problema este că pragma Perl "foloseste constantă" creează într-adevăr o subrutină în pachetul actual, al cărui nume este primul argument al pragmei și a cărui valoare este ultima.

În Perl, odată ce o subrutină este declarată, ea poate fi numită fără parente.

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

Din fericire, puteți invoca constanta folosind punctuație explicită, cum ar fi parente sau ampersand sigil.

Cu toate acestea, am o întrebare pentru dvs.: de ce folosiți constante pentru cheile hash?

Mă pot gândi la câteva scenarii care te-ar putea duce în această direcție:

  1. Aveți nevoie de control asupra tastelor care pot fi în hash.

  2. Doriți să eliminați numele cheilor în cazul în care acestea se modifică ulterior

În cazul numărului 1, probabil că constantele nu vor salva hash-ul. În schimb, luați în considerare crearea unei clase care are setteri publici și getters care utilizează un hash vizibil numai pentru obiect. Aceasta este o soluție foarte asemănătoare cu cea a Perl, dar foarte ușor de făcut.

În cazul numărului 2, aș susține în continuare puternic pentru o clasă. Dacă accesul la hash este reglat printr-o interfață bine definită, numai implementatorul clasei este responsabil pentru obținerea corectă a numelor cheilor hash. În acest caz, nu aș sugera folosirea constantelor.

Sper că acest lucru vă ajută și vă mulțumim pentru timpul acordat.

0
adăugat