2011-04-22 22 views
8

Duplicar posibles:
How can I convert the stringified version of array reference to actual array reference in Perl?Perl: ¿Convertir cadena a referencia?

tengo "escalar (0x8ec3a94)" como una cadena literal. ¿Puedo forzar Perl a convertir esto en una referencia y luego seguirlo?

IE, dígale a Perl: "busque en la ubicación de memoria 0x8ec3a94, y trate lo que hay como un escalar"?

Relacionado con: Perl: Unwrapping list inside-out doesn't work?

Y sí, soy consciente de que esto es una cosa horrible que hacer.

+0

relacionadas: http://stackoverflow.com/questions/1671281/how-can-i-convert-the-stringified-version-of-array-reference-to-actual-array-refe. No es estrictamente un tonto ya que ese fue sobre ARRAY. – Andy

+1

No, una referencia no es un puntero. ¿Cómo se convirtió en una cuerda en primer lugar? Ahí es donde está el error. – shawnhcorey

+0

@shawnhcorey, no, no es un puntero, pero contiene la misma información, ver mi respuesta –

Respuesta

3

Lo más cercano que puede obtener es con Tie::RefHash. La versión del pobre hombre mete referencias en un hash

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

y luego lo saca adelante

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

Esto tiene un montón de inconvenientes enfoque. ¿Por qué quieres hacerlo de esta manera?

+0

Estoy tratando de analizar algo "de adentro hacia afuera", comenzando con la referencia más interna y trabajando para salir. – barrycarter

3

Desde el enlace proporcionado por Andy, pruebe el Inline::C approach. Deseará usar SV* en lugar de AV*, pero debería funcionar.

Me he burlado de un ejemplo, extendiendo el método que se muestra en ese enlace. Con mi conocimiento limitado de C, creo que he evitado un Segfault cuando la referencia ya no apunta a nada (prueba al quitar el comentario de los refuerzos internos, lo que permite que $ text caiga fuera del alcance). Como utilizo newRV_inc en la sección C, se incrementa el recuento de referencias para $text. Por lo tanto, si $text queda fuera del alcance, pero su referencia encontrada ($recovered_ref) aún existe, el valor todavía está disponible, como se esperaba (pruebe anulando el comentario de las llaves externas).

Este método parece funcionar para cualquier tipo de referencia. No estoy seguro acerca de los objetos, pruébelo si lo desea. Para obtener más información, perldoc Inline::C será de ayuda, pero deberá leer perldoc perlguts y posiblemente incluso perldoc perlapi para continuar por esta ruta.

#!/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

De forma predeterminada, StackOverflow muestra las respuestas ordenadas por puntaje, luego establece las uniones (aparentemente) al azar. Esto significa que el enlace al que se refiere puede aparecer debajo de su respuesta o (en las preguntas con más actividad) aparecen varios lugares encima de usted con otros enlaces intermedios. Por lo tanto, no lo mencione como "el enlace de arriba" si desea que las personas sepan a qué enlace se refiere. –

+0

@Dave, es el mismo enlace que he publicado, solo el mío apunta a una respuesta específica en el interior. ¿Debería haber publicado dos enlaces a la misma pregunta? Esto debería hacer. –

+1

He estado esperando una razón simple para aprender a hacer y empaquetar un módulo XS para CPAN (acabo de lanzar mi primer módulo Pure-Perl hace unos días). ¿Esto es algo que la gente querría en CPAN? Me daría una razón para intentarlo. –