To reply to your various posts in this thread in one place:

Circular references are one of those concepts I blew off and didn't worry about. It's probably time I started worrying.

It's definitely something to keep in mind when building object trees like you are. I tried out some different ways to locate circular references in this node, but applying that to your code just shows a bunch of circular references of Class::MOP::* objects, so I'd guess Moose is wrapping everything up and hiding the actual circular references. Applying it to my code above shows them a little more clearly.

I stored a reference to a reader method ... it provides encapsulation

Personally, I don't think hiding the "big object" in a code ref adds much. Consider that the class for the big object should already provide all the necessary encapsulation, and so I think there's nothing wrong with simply providing a getter on the "little object" class that returns the big object. You might just consider making this field read-only.

... the weak_ref => 1 attribute property. However, slapping that in breaks my code.

Yes, I can confirm that in your code putting weak_ref on either the little_objs or get_obj_by_id causes "Can't use an undefined value as a HASH/subroutine reference" errors. Also, if I take your code as shown here, and add a sub DESTROY to track destruction like I showed above, it shows the memory leak. Since adding a level of indirection with the code ref doesn't seem to break my code above, at the moment I'm guessing that it's the combination of Moose's weak_ref and the code ref that is causing the problem, but I haven't investigated this further, because I can fix the problem by doing what I said above, just giving the little object a reference to the big object:

Working code:

#!/usr/bin/env perl use warnings; use 5.014; package BigObj { use Moose; has 'little_objs' => ( is => 'rw', isa => 'HashRef', default => sub { {} } ); sub add_little_obj { my ($self, $little_obj) = @_; $little_obj->big_obj($self); $self->little_objs->{$little_obj->id} = $little_obj; } sub get_little_obj { my ($self, $id) = @_; return $self->little_objs->{$id}; } sub DESTROY { print "DESTROY ",ref(shift),"\n" } } package LittleObj { use Moose; has 'id' => (is => 'rw'); has 'big_obj' => (is => 'rw', weak_ref=>1); sub alter_another_little_object { my ($self, $id) = @_; $self->big_obj->get_little_obj($id)->do_stuff; } sub do_stuff { print "I'm doing stuff to: ",shift->id,"\n" } sub DESTROY { my $self = shift; print "DESTROY ",ref($self)," id=",$self->id,"\n" } } my $big = BigObj->new(); my $little1 = LittleObj->new(id=>'little1'); my $little2 = LittleObj->new(id=>'little2'); $big->add_little_obj($little1); $big->add_little_obj($little2); $little1->alter_another_little_object('little2'); print "Clearing vars...\n"; $little1 = undef; $little2 = undef; $big = undef; END { print "END\n" } __END__ I'm doing stuff to: little2 Clearing vars... DESTROY BigObj DESTROY LittleObj id=little2 DESTROY LittleObj id=little1 END

In reply to Re^3: Is there an advantage to storing references to objects in an attribute instead of the object itself? by haukex
in thread Is there an advantage to storing references to objects in an attribute instead of the object itself? by nysus

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.