Cum pot determina tipul de referință binecuvântată în Perl?

În Perl, un obiect este doar o referință la oricare dintre tipurile de date Perl de bază care a fost binecuvântată într-o anumită clasă. Când utilizați funcția ref() pe o referință nesupusă, vi se va spune la ce tip de date se referă referința. Cu toate acestea, atunci când apelați ref() pe o referință binecuvântată, vi se returnează numele pachetului la care a fost binecuvântată referința.

Vreau să știu tipul real al referinței binecuvântate. Cum pot determina acest lucru?

0
fr hi bn

3 răspunsuri

Și primul meu gând pe această temă a fost: "Obiectele din Perl sunt întotdeauna refuzuri de hash, deci ce hack?"

Dar, Scalar :: Util :: reftype este răspunsul. Vă mulțumim că ați pus întrebarea aici.

Iată un fragment de cod pentru a demonstra acest lucru .. (în cazul în care este de nici un folos pentru oricine).

$> perl -e 'use strict; use warnings "all"; my $x = [1]; bless ($x, "ABC::Def"); use Data::Dumper; print Dumper $x; print ref($x) . "\n"; use Scalar::Util "reftype"; print reftype($x) . "\n"'`

ieşire:

$VAR1 = bless( [
                 1
               ], 'ABC::Def' );
ABC::Def
ARRAY
0
adăugat
Obiectele sunt adesea implementate ca referințe pentru hash, dar nu este o cerință. Un obiect poate fi orice tip de referință.
adăugat autor brian d foy, sursa

Scalar::Util::reftype() is the cleanest solution. The Scalar::Util module was added to the Perl core in version 5.7 but is available for older versions (5.004 or later) from CPAN.

De asemenea, puteți să sondați cu UNIVERSAL :: isa() :

$x->isa('HASH')             # if $x is known to be an object
UNIVERSAL::isa($x, 'HASH')  # if $x might not be an object or reference

Evident, ar trebui să verificați și tipurile ARRAY și SCALAR . Modulul UNIVERSAL (care servește ca clasă de bază pentru toate obiectele) a făcut parte din nucleu de la Perl 5.003.

Un alt mod - ușor, dar puțin murdar - este de a strânge referința. Presupunând că clasa nu a supraîncărcat stringificarea, veți primi ceva asemănător cu Class = HASH (0x1234ABCD) , pe care îl puteți parsa pentru a extrage tipul de date care se află subiacent:

my $type = ($object =~ /=(.+)\(0x[0-9a-f]+\)$/i);
0
adăugat
Vrei doar eval {$ x-> isa ($ type)}; Dacă asta nu este un obiect, te întorci fals. Dacă nu este tipul potrivit, obțineți fals și, dacă este tipul potrivit, veți deveni adevărați. :)
adăugat autor brian d foy, sursa

Probabil că nu ar trebui să faceți asta. Tipul de bază al unui obiect este un detaliu al implementării pe care nu ar trebui să-l faceți. De ce vrei să știi asta?

0
adăugat
Sunt de acord și știam că cineva ar face acest comentariu. Chiar aveam nevoie de acest lucru în timp ce încercam să găsesc o structură pe care un modul a creat-o pentru a putea modifica modulul. Am vrut să șterg o anumită cheie din orice hashes din structură deoarece conținea un JPEG brut.
adăugat autor Ryan Olson, sursa
Mai târziu am descoperit că aș putea folosi Data :: Dumper :: sortkeys pentru a filtra aceste date, astfel că Data :: Dumper nu a produs megaocteți de ieșire binară.
adăugat autor Ryan Olson, sursa