有没有办法让Perl将数组引用的字符串化版本(例如ARRAY(0x8152c28))转换为实际的数组引用?
例如
perl -e 'use Data::Dumper; $a = [1,2,3];$b = $a; $a = $a.""; warn Dumper (Then some magic happens);'
Run Code Online (Sandbox Code Playgroud)
会屈服
$VAR1 = [
1,
2,
3
];
Run Code Online (Sandbox Code Playgroud)
yst*_*sth 17
是的,你可以这样做(即使没有内联C).一个例子:
use strict;
use warnings;
# make a stringified reference
my $array_ref = [ qw/foo bar baz/ ];
my $stringified_ref = "$array_ref";
use B; # core module providing introspection facilities
# extract the hex address
my ($addr) = $stringified_ref =~ /.*(0x\w+)/;
# fake up a B object of the correct class for this type of reference
# and convert it back to a real reference
my $real_ref = bless(\(0+hex $addr), "B::AV")->object_2svref;
print join(",", @$real_ref), "\n";
Run Code Online (Sandbox Code Playgroud)
但不要这样做.如果您的实际对象被释放或重用,您最终可能会得到段错误.
无论你实际想要实现什么,肯定有更好的方法.对另一个答案的评论表明,字符串化是由于使用引用作为哈希键.作为回应,更好的方法是经过良好战斗测试的 Tie :: RefHash.
第一个问题是:你真的想这样做吗?
这个字符串来自哪里?
如果它来自你的Perl程序之外,指针值(十六进制数字)将毫无意义,并且没有办法做到这一点.
如果它来自您的程序内部,那么首先不需要对其进行字符串化.
是的,有可能:使用Devel :: FindRef。
use strict;
use warnings;
use Data::Dumper;
use Devel::FindRef;
sub ref_again {
my $str = @_ ? shift : $_;
my ($addr) = map hex, ($str =~ /\((.+?)\)/);
Devel::FindRef::ptr2ref $addr;
}
my $ref = [1, 2, 3];
my $str = "$ref";
my $ref_again = ref_again($str);
print Dumper($ref_again);
Run Code Online (Sandbox Code Playgroud)