Is there any way to get Perl to convert the stringified version e.g (ARRAY(0x8152c28)) of an array reference to the actual array reference?
For example
perl -e 'use Data::Dumper; $a = [1,2,3];$b = $a; $a = $a.""; warn Dumper (Then some magic happens);'
would yield
$VAR1 = [
1,
2,
3
];
The Magic of Array References in Perl is to use array references to access nested data. The syntax for accessing a referenced array seems a little trick at first, and I’ll put the code here, and then explain how it works. The reference is actually created using the backslash symbol. Perl flattens all nested data, and mashes all the data together.
To assign an array reference into a variable, use the backslash (\) operator as shown below If you try to print the $array_ref variable, you’ll get something like the following. The Perl array reference can also be passed to a subroutine as shown below.
This statement gives the first element of @numbers array. This is same as $numbers [0] Instead of storing the reference into the variable, the array elements can be accessed directly from Perl built-in variable. # Get all the elements of @numbers array. @ { $_ [0] } # Get a particular element.
The Perl array reference can also be passed to a subroutine as shown below. In the above code snippet, we need to de-reference the array, so that the subroutine can take the elements from the original array. Following are some of the advantages of passing the reference to a subroutine, instead of passing the whole array.
Yes, you can do this (even without Inline C). An example:
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";
but don't do that. If your actual object is freed or reused, you may very well end up getting segfaults.
Whatever you are actually trying to achieve, there is certainly a better way. A comment to another answer reveals that the stringification is due to using a reference as a hash key. As responded to there, the better way to do that is the well-battle-tested Tie::RefHash.
The first question is: do you really want to do this?
Where is that string coming from?
If it's coming from outside your Perl program, the pointer value (the hex digits) are going to be meaningless, and there's no way to do it.
If it's coming from inside your program, then there's no need to stringify it in the first place.
Yes, it's possible: use 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);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With