2011-04-22 11 views
8

Eventuali duplicati:
How can I convert the stringified version of array reference to actual array reference in Perl?Perl: convertire la stringa in riferimento?

ho "SCALARE (0x8ec3a94)" come una stringa letterale. Posso forzare Perl a trasformarlo in un riferimento e poi seguirlo?

IE, dire a Perl: "cercare nella posizione di memoria 0x8ec3a94, e trattare qualunque cosa ci sia come uno scalare"?

relativi a: Perl: Unwrapping list inside-out doesn't work?

E sì, mi rendo conto che è una cosa orribile da fare.

+0

correlate: http://stackoverflow.com/questions/1671281/how-can-i-convert-the-stringified-version-of-array-reference-to-actual-array-refe. Non strettamente un dupe poiché quello era su ARRAYs. – Andy

+1

No, un riferimento non è un puntatore. Come è diventata una stringa in primo luogo? Ecco dove si trova l'errore. – shawnhcorey

+0

@shawnhcorey, no non è un puntatore, ma contiene le stesse informazioni, vedere la mia risposta –

risposta

3

Il più vicino possibile è con Tie::RefHash. La versione del poveretto infila riferimenti in un hash

$registry{"$ref"} = $ref; 

e poi tira fuori più tardi

print ${ $registry{"SCALAR(0x8ec3a94)"} }, "\n"; 

Questo approccio ha un sacco di svantaggi. Perché vuoi farlo in questo modo?

+0

Sto cercando di analizzare qualcosa "dentro e fuori", iniziando dal riferimento più interno e lavorando alla mia uscita. – barrycarter

3

Dal collegamento fornito da Andy, provare lo Inline::C approach. Si vorrà utilizzare SV* anziché AV*, ma dovrebbe funzionare.

Ho preso in mano un esempio, estendendo il metodo mostrato in quel collegamento. Con la mia conoscenza limitata di C, penso di aver impedito un Segfault quando il riferimento non punta più a nulla (test annullando i commenti alle parentesi interne, consentendo a $ text di uscire dall'ambito). Perché io uso newRV_inc nella sezione C, il conteggio dei riferimenti per $text viene incrementato. Pertanto se $text non rientra nell'ambito, ma il suo riferimento trovato ($recovered_ref) esiste ancora, il valore è ancora disponibile, come previsto (test annullando le parentesi graffe esterne).

Questo metodo sembra funzionare per qualsiasi tipo di riferimento. Non sei sicuro degli oggetti, provaci se vuoi. Per ulteriori informazioni, il numero perldoc Inline::C sarà di aiuto, ma sarà necessario leggere perldoc perlguts ed eventualmente anche perldoc perlapi per continuare su questo percorso.

#!/usr/bin/perl 

use strict; 
use warnings; 

use Inline 'C'; 

my $stringified_ref_text; 
my $stringified_ref_array; 
my $recovered_ref_text; 
my $recovered_ref_array; 

#{ 
    #{ 
    my $text = "Hello World"; 
    my @array = qw"Hello World!"; 

    $stringified_ref_text = \$text . ""; 
    $stringified_ref_array = \@array . ""; 

    print $stringified_ref_text . "\n"; 
    print $stringified_ref_array . "\n"; 
    #} 

    $recovered_ref_text = recover_ref($stringified_ref_text); 
    $recovered_ref_array = recover_ref($stringified_ref_array); 
#} 

print $$recovered_ref_text . "\n"; 
print "$_\n" for @$recovered_ref_array; 

sub recover_ref { 

    my $input = shift; 

    my $addr; 
    if ($input =~ /0x(\w+)/) { 
    $addr = hex($1); 
    } else { 
    warn "Could not find an address"; 
    return undef; 
    } 
    my $ref = _recover_ref($addr) or undef; 

    return $ref; 
} 

__DATA__ 
__C__ 

SV* _recover_ref(int address) { 
    if (address) 
    return newRV_inc((SV*) address); 

    return 0; 
} 
+0

Per impostazione predefinita, StackOverflow mostra le risposte ordinate per punteggio, quindi stabilisce i legami (apparentemente) casualmente. Ciò significa che il link a cui ti stai riferendo potrebbe apparire sotto la tua risposta o (nelle domande con più attività) apparire in diversi punti sopra di te con altri collegamenti in mezzo. Quindi, per favore, non chiamarlo "link sopra" se vuoi che le persone sappiano quale link intendi. –

+0

@Dave, è lo stesso link che ho inserito, solo i miei punti per una risposta specifica all'interno. Devo aver postato due link alla stessa domanda? Questo dovrebbe fare. –

+1

Ho aspettato un semplice motivo per imparare a creare e impacchettare un modulo XS per CPAN (ho appena rilasciato il mio primo modulo Pure-Perl qualche giorno fa). È qualcosa che la gente vorrebbe su CPAN? Mi darebbe un motivo per provarlo. –

Problemi correlati