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

Greetings Monasteers, I am having a battle with object inheritance, specifically the problem that @ISA doesn't bequeath subs/functions only methods. I wanted to derive everything from Class::PObject so it would be nicely storable, but I think my mastery of OO Perl is wanting. Starting at the top,
#!/usr/bin/perl package myStorableBase; use Class::PObject; my @basedef = ["id", "name", "email", "phone"]; pobject # pobj is a persistent object { # can be saved and loaded columns => @basedef, # the entries driver => 'db_file', # to a db file normal unix datasource => "./data" # in this place }; sub thingysub { my $whatever = shift; return 1; } 1;
Which gives me a myStorable that I am happy with. In another file we have,
#!/usr/bin/perl package MyHuman; use myStorableBase; @ISA = ("myStorableBase"); # I am one of those cocky little monkeys with the hands and the fire a +nd the little green # pieces of paper. (aka 'Ugly Bag of mostly-water') # 1;
Human has a number of attributes and accessor/inspector methods that I've stripped out for clarity. However when I use myHuman I can's save the blighter, because it seems myHuman knows nothing about the subclass Class::PObject::DBM from which it gets its save(). I'm also confused becasue PObject doesn't seem to have a new constructor, it constructs a new instance using a subroutine 'pobject()' which I think is the source of all my woes. I need a PObject master, the docs don't say a lot about subclassing. Beat me with a cluebat! (or some more advanced Perl OO reading links) Cheers, Andy

Replies are listed 'Best First'.
Re: Can't inherit subroutines - workaround?
by simonm (Vicar) on May 08, 2004 at 20:56 UTC
    ...it seems myHuman knows nothing about the subclass Class::PObject::DBM from which it gets its save().

    I spent a few minutes poking around the internals of Class::PObject trying to find some helpful documentation, but was a bit confused -- you mention a "subclass Class::PObject::DBM" but the PObject documentation seems to indicate that instead of inheriting, it should delegate to a separate Class::PObject::Driver::DBM object.

    Are you using the most recent version of Class::PObject?

    I'm also confused becasue PObject doesn't seem to have a new constructor, it constructs a new instance using a subroutine 'pobject()' which I think is the source of all my woes.

    The Class::PObject docs clearly show the use of a constructor as "$person = new Person();"; the "pobject()" subroutine is for initializing a class not a single instance.

      Thanks for looking Simon, you are quite right, I was muddled about the constructor, of course pobject makes the class and its instantiated with the usual new().

      Can you explain a little bit more what you mean by 'delegate' in a Perl sense, because the save() method I am after is, being file/system specific, somewhere in that Class::PObject::Driver::DBM I presume.

      When I dump the keys and methods that I get with myHuman I see everything intrinsic to myHuman, and the columns hash from PObject, but the save() method has got lost.

      Iyho would I be better _deriving_ a new class (however one does that in Perl) or hacking about with import / exports or just writing my own storable object from the top.

      I just found a snippet that lets me recurse up through all the parents @ISAs so it might help me debug where the reference to save is getting lost.
      btw, yes its the latest PObject I could find installed less than a week ago. Thanks Simon,
      Andy
        Can you explain a little bit more what you mean by 'delegate' in a Perl sense, because the save() method I am after is, being file/system specific, somewhere in that Class::PObject::Driver::DBM I presume.

        I mean that a reference to a driver object is stored within each PObject class's $props->{driver}, and that calling save on an individual object is implemented by making a call to that driver's save method to do the actual work.

        The initialization is done in Class::PObject's pobject() method, which also causes your class to inherit from Class::PObject::Template, which is where the main save() method is located; it in turn calls the save() method in Class::PObject::Driver::DBM.

        Iyho would I be better _deriving_ a new class...

        You've already done that, by declaring that @ISA = ("myStorableBase");.

        Are you creating your MyHuman objects correctly, with MyHuman->new()?