可能重复:
How can I convert the stringified version of array reference to actual array reference in Perl?
我将“SCALAR(0x8ec3a94)”作为文字字符串。我可以强制Perl 把它变成参考然后跟着它?
IE,告诉Perl:“查看内存位置0x8ec3a94,并对待 什么是标量“?
相关:Perl: Unwrapping list inside-out doesn't work?
是的,我知道这是一件可怕的事情。
答案 0 :(得分:3)
最接近的是Tie::RefHash。穷人的版本在哈希
中填充引用$registry{"$ref"} = $ref;
然后将其拉出来
print ${ $registry{"SCALAR(0x8ec3a94)"} }, "\n";
这种方法有很多缺点。你为什么要这样做?
答案 1 :(得分:3)
从Andy提供的链接中,尝试Inline::C
approach。您需要使用SV*
而不是AV*
,但它应该可以使用。
我已经模拟了一个示例,扩展了该链接中显示的方法。由于我对C的了解有限,我认为当引用不再指向任何内容时我已经阻止了Segfault(通过取消注释内部括号进行测试,允许$ text超出范围)。因为我在C部分使用newRV_inc
,所以$text
的引用计数会递增。因此,如果$text
超出范围,但其找到的引用($recovered_ref
)仍然存在,则该值仍然可用,正如预期的那样(通过取消注释外部大括号进行测试)。
此方法似乎适用于任何类型的引用。不确定对象,如果你愿意,可以试一试。有关详细信息perldoc Inline::C
会有所帮助,但您需要阅读perldoc perlguts
,甚至可能需要perldoc perlapi
才能继续沿着此路径前进。
#!/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;
}