ivo Welch ivo Welch - 1 year ago 85
Perl Question

perl storing hash in %ENV

I want to (ab-)use the global %ENV to store a hash. This seems to work differently for %ENV than for ordinary hashes. in the program below, the

still contains
'myhash' => 'HASH(0x7ffad8807380)'
and the
is still around. is it possible to convert the hex address back to point at its location, instead of just containing the string? I guess I could serialize and unserialize the hash instead. what is the right way to do this?

#!/usr/bin/perl -w

use common::sense;
use Data::Dumper;

my %QENV = ( nohash => 'noh' );
my %ahash= ( hv1 => 'htext1', hv2 => 'htext2' );
$QENV{'myhash'} = \%ahash;
print "works: ". Dumper(\%QENV)."\n\n\n";

$ENV{'myhash'} = \%ahash;
print "fails: ". Dumper(\%ENV)."\n";

Answer Source

%ENV is a magical hash. It reflects the process's environment. Reading from it reads from the environment, and writing to it changes the environment.

If you can guarantee the referenced variable is still alive (by it still being in scope or by it having its REFCNT increased), you can indeed create a reference to it from the address.

use strict;
use warnings;

use Data::Dumper;

use Inline C => <<'__EOS__';

   SV* _newRV(IV iv) {
      return newRV((SV*)iv);


my %hash = ( a => 1, b => 2 );
my $ref = \%hash;
my $ref_string = "$ref";
my $addr = hex( ( $ref_string =~ /\((.*)\)/ )[0] );
my $ref2 = _newRV($addr);

I have no idea why you'd want to do this. It would not permit another process to access the data since one process can't access the memory of another.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download