Tetramin has asked for the wisdom of the Perl Monks concerning the following question:

If I have a reference $ref to a data structure or a blessed reference, then if I print "$ref" I get strings like "HASH(0x17653d4)" or "Module=HASH(0x17653d4)". I don't know what this means or what use it is intended for. Are these strings unique? Can I maybe use them as keys in a hash to store object individual and private information? I have tried this in the following code. It even happend to work but I wouldn't dare to use it whithout knowing what these strings really are. If you know a place that explains the meaning of stringified references, please post it.
$o = new Module; $o->method; package Module; { my %obj; sub new { my $class = shift; my $self = {@_}; bless $self, ref($class) || $class; $obj{"$self"} = { say => "Hello World"}; $self; } sub method { my $self = shift; my $obj = $obj{"$self"}; return $obj->{say}; } DESTROY { my $self = shift; delete $obj{"$self"}; } }

Replies are listed 'Best First'.
Re (tilly) 1: What is HASH(0x17653d4) for?
by tilly (Archbishop) on Nov 02, 2001 at 01:28 UTC
    Unless an object provides a stringification operation using overload, it is guaranteed that no two references at the same time will stringify in the same way. So yes, you can use them in a hash.

    However if you allocate, free, then reallocate a variable, the second one may be used where the first one was. For instance consider this code:

    sub gen_ref { [@_]; } print gen_ref(), "\n"; my $keep_ref = gen_ref(); print $keep_ref, "\n"; print gen_ref(), "\n";
    If you run that, you will find that the first two references that were generated at different times were named the same as each other. But when you tried to create a new one while the old one existed, Perl gave it a different name. So if the hash keys live longer than the references you are indexing into, then you may have a problem.

    What is going on behind the scenes is that the name specifies the memory location where you used the data. And if Perl can it reuses the old memory location. If that is in use, then it uses a new one.

      Thanks to all the posters above.

      So a new entity gets a new string. That's all fine with me. Suppose $c = $d = new Something. Then $c and $d point to the same memory location and have the same stringification. Everything as expected. The DESTROY will delete the key if the object dies.

      Until now it sounds like I can use stringified refs to identify an object. Except for this: is it possible that the stringification changes only by time or by adding/deleting/changing data in the underlying object? The keys wouldn't reliably identify the object anymore.

      Assuming this doesn't happen wouldn't that be interesting for certain modules, like CGI.pm? $query->{name} would be $query->param('name') an keys %$query would contain nothing else but param() because extra information that is used by the module's subroutines can be outsourced to a hash with ref-strings as keys. $query would act like a normal hash reference and still be blessed to the modules subroutines. I already see myself experimenting with this alot.

        Once the reference is assigned a location, it never moves. The data behind it may get moved, but the reference you see doesn't.

        There are only four major gotchas to using references as hash keys that I know of.

        1. It depends on stringification, so if the generator of the reference likes overloading, all bets are off.
        2. From the string representation of a reference you can't get the reference back.
        3. Names are guaranteed unique at any point in time, but not over time. As demonstrated in my code sample, it is possible for 2 references to get the same name if the second is created after the first is destroyed.
        4. If you ever make your program persistent by freezing and thawing data structures (eg with Storable or Data::Dumper) then the reconstructed references will be at new addresses.
        And yes, this fact does have some neat uses.
Re: What is HASH(0x17653d4) for?
by japhy (Canon) on Nov 02, 2001 at 01:14 UTC
    The "Class=TYPE(LOC)" tells you what class a reference is blessed into (if any), the underlying data type being referred to, and the location in memory. The location in memory isn't terribly useful, though.

    _____________________________________________________
    Jeff[japhy]Pinyan: Perl, regex, and perl hacker.
    s++=END;++y(;-P)}y js++=;shajsj<++y(p-q)}?print:??;

Re: What is HASH(0x17653d4) for?
by premchai21 (Curate) on Nov 02, 2001 at 01:15 UTC
    A stringified reference indicates the type and address of that which the original reference referenced. They are unique to the point that references to different entities will have different stringifications. Note however that you cannot get the original reference back from the stringified version; you cannot, for instance, do this:
    my $x = 5; my $y = \$x; $y = "$y"; $$y = 8; # Error! $y is now the stringified form # of the reference, and can't be referenced.
Re: What is HASH(0x17653d4) for?
by perrin (Chancellor) on Nov 02, 2001 at 01:21 UTC
    Getting the memory address is pretty useful for determining whether or not two references are actually pointing at the same thing. If the addresses match, you have two references to the same hash.