http://qs321.pair.com?node_id=375297


in reply to Why is a hash the default "object" in oo perl?

Looks like you've independently discovered Abigail's favorite type of Inside-out objects. It's the only way you can subclass without caring about the base class implementation. They are a pretty good idea.

I use inside-out objects for my database persistence module, because it also helps with synchronization. Each object corresponds to a row in some table. So instead of using the pointer address as the key to the instance data hash, I use the primary key from the database. This is a big win, because there may be many objects instantiated that correspond to the same row in the database. When one gets updated, it's updated in the central hash and any other objects corresponding to that row can see it. If I had used blessed hashrefs as objects, it would have been a big pain to push these updates out to all the necessary hashrefs.

What your implementation is missing, however, is a DESTROY method. When doing these inside-out objects, your %agedata hash keeps filling up. When an object is destroyed, you never clean up after yourself. For persistent environments like mod_perl, this can lead to quite a memory leak in the instance data hashes. So be sure to add:

sub DESTROY { delete $agedata{+shift}; }
.. and clear out all instance data hashes.

blokhead

Replies are listed 'Best First'.
Re^2: Why is a hash the default "object" in oo perl?
by bart (Canon) on Jul 18, 2004 at 10:29 UTC
    I use inside-out objects for my database persistence module, because it also helps with synchronization.
    I'm intrigued. Can you show us some code?

    One more thing:

    So instead of using the pointer address as the key to the instance data hash, I use the primary key from the database. This is a big win, because there may be many objects instantiated that correspond to the same row in the database.
    in contrast with:
    So be sure to add:
    sub DESTROY { delete $agedata{+shift}; }
    .. and clear out all instance data hashes.
    Surely that will pose a problem if you can have several objects pointing to the same hash item? What do you do about that, do you keep a reference count yourself?

    And I've been pondering if weak references could be used, to do the cleanup automatically for you. I just don't see how...

      I once had an LRU cache purge itself using DESTROY on linked list nodes, that knew how to delete themselves from a hash. The only way I found was to tell the nodes which lookup key they had.

      Retrospectively i would have the hash point to dually linked list nodes, which knew their keys too. Then each access would not create a new node, but rather bubble it up. That way the linked list doesn't grow.

      To purge either implementation, you just pop off the linked list, and let the ref count reach zero.

      -nuffin
      zz zZ Z Z #!perl
      See Class::Tables for the full code. The basic idea is that the object implementation is a blessed scalar holding the tuple's primary key. I can also tell what database table it belongs to by what class it's blessed into. I use these two pieces of information to address a deep hash with all the accessor data. The general idea is:
      my $DATA; sub id { ${+shift} } # $obj->column_name() # $obj->field("column_name") sub field { my ($self, $col) = @_; my $table = (ref $self)->_table; my $id = $self->id; return $DATA{$table}{$id}{$col}; }
      The DESTROY method I gave in the previous post was for the benefit of theAcolyte and the basic inside-out mechanism. You're right that in my code, since the data should stay around as long as there's an object that might need it, I have to do something a little more clever. I end up doing my own form of reference counting. Each time I make an object, I increment $COUNT{$table}{$id}. Each time an object is destroyed, I decrement that count and if the count became zero, clear out the appropriate part of the %DATA hash (and %COUNT as well).

      blokhead

Re^2: Why is a hash the default "object" in oo perl?
by theAcolyte (Pilgrim) on Jul 19, 2004 at 00:02 UTC
    Thanks for the link to Abagail's inside-out objects. I've seen references to it before but never read up on it, and had no clue what it meant. Also, thanks for the notion about the destroy method -- you're quite right in that it didn't occour to me that when an object goes out of scope, its attributes are still existing the %agedata hash. While its not so bad in a non-persistant environment (how I ususally work) it would be bad under mod-perl.