Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

hash reference to itself

by ExReg (Priest)
on Aug 02, 2016 at 16:55 UTC ( [id://1169014]=perlquestion: print w/replies, xml ) Need Help??

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

I am trying to figure out if it is possible for a hash value to reference a key value in the same hash. As a much simplified example, suppose I have the following:

use strict; my %hash = ( name => "foo", code => sub{ print "name: ", "foo", "\n"; }, ); $hash{code}->(); _____ name: foo

"foo" is the value of the name key and is also in the code subroutine. Is it possible to have a hash refer to itself with something like

use strict; my %hash = ( name => "foo", code => sub{ print "name: ", $hash{name}, "\n"; }, ); $hash{code}->();

Obviously this syntax does not work, but is there a way to do this?

Replies are listed 'Best First'.
Re: hash reference to itself
by dave_the_m (Monsignor) on Aug 02, 2016 at 17:41 UTC
    Note that a self-referential hash will leak. This code consumes several Gb after running for a few seconds:
    while (1) { my %h; $h{a} = \%h; }

    You may need to use weaken() from Scalar::Util

    Dave.

      Good to know. Thanks!

Re: hash reference to itself
by Anonymous Monk on Aug 02, 2016 at 17:09 UTC

    Declare the hash before assignment.

    my %hash; %hash = ...

      When my forehead hit the desk, I woke up several people sleeping around me. I don't expect this kind of mental flatulence until Fridays. Thanks! Just what I needed.

        Note that this approach will leak memory unless you do the following when you're done with the hash:
        %hash = ();
Re: hash reference to itself
by VinsWorldcom (Prior) on Aug 02, 2016 at 17:11 UTC

    Perl can do object-oriented code.

    #!perl use strict; use warnings; package MyPkg; sub name { return 'foo'; } sub print { print "name: " . name(); } package main; print MyPkg->name() . "\n"; MyPkg->print();

    UPDATE: Actually *not* OO as YourMother points out below.

      There is no object here, just class calls which might as well be package calls.

      print MyPkg::name(), $/; MyPkg::print();

        You're right. Is this better?

        #!perl use strict; use warnings; package MyPkg; sub new { my ($self, $name) = @_; my %hash = ( name => $name ); return bless \%hash; } sub print { my $self = shift; print "name: " . $self->{name}; } package main; my $obj = MyPkg->new('foo'); $obj->print();

      I think if I had the time to do it, OO may have been a better way to do it. But for now, I will have to stick with the huge hashes I have. Thanks.

Re: hash reference to itself
by talexb (Chancellor) on Aug 02, 2016 at 17:05 UTC

    What problem are you trying to solve here?

    Alex / talexb / Toronto

    Thanks PJ. We owe you so much. Groklaw -- RIP -- 2003 to 2013.

      I have a rather large hash that has a somewhat similar structure. There are many keys containing subs that use another key to print messages. I wanted to bring those keys up a level ( the name key was inside the code sub) and another piece of code wanted to see the name value. Hence I wanted to bring the name up where it was visible to others. Anonymous Monk hit the nail on the head.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1169014]
Approved by talexb
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others wandering the Monastery: (4)
As of 2024-04-25 05:29 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found