Perl:将字符串转换为引用?

时间:2011-04-22 21:49:32

标签: perl coding-style

  

可能重复:
  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?

是的,我知道这是一件可怕的事情。

2 个答案:

答案 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;
}