highly restrictive sub-classing

Discussion in 'Perl Misc' started by xhoster@gmail.com, Aug 4, 2008.

  1. Guest

    I have a lot of scripts that use a memory-hungry module, but most of them
    use only a small subset of that module's features, and it should be
    possible to implement that subset in a more memory efficient way.

    I want to "subclass" the memory hungry module. Many of the methods, ones
    which are rarely used and can't be made memory efficient, will not be
    implemented in the subclass.

    I could define subs in the subclass for each such method, invoking croak or
    die so the call doesn't get dispatched up the @ISA list. But I want the
    default to lie the other way around, methods are unimplemented unless other
    specified.

    I guess I could walk the superclass's symbol table, automatically defining
    a croaking sub for every subroutine in that symbol table unless they are in
    my "implemented" list. But that seems rather hackish. Is there a better
    way to do that?

    Other options would be to *not* put the superclass in @ISA, and manually
    redispatch calls to the superclass when that is the proper thing to do,
    with unimplemented ones getting exceptions from Perl rather than explicit
    ones. Is there some pitfall in doing this?

    Or I could just do a complete code-fork and have the two modules completely
    unrelated other than happening to have many method names in common. This
    loses improvements made to the superclass. But since any new methods would
    have to be manually inspected for compatibility before adding them to the
    redispatch list anyway, I am not sure this is really a meaningful problem.

    Xho

    --
    -------------------- http://NewsReader.Com/ --------------------
    The costs of publication of this article were defrayed in part by the
    payment of page charges. This article must therefore be hereby marked
    advertisement in accordance with 18 U.S.C. Section 1734 solely to indicate
    this fact.
     
    , Aug 4, 2008
    #1
    1. Advertising

  2. smallpond Guest

    On Aug 4, 12:56 pm, wrote:
    > I have a lot of scripts that use a memory-hungry module, but most of them
    > use only a small subset of that module's features, and it should be
    > possible to implement that subset in a more memory efficient way.
    >
    > I want to "subclass" the memory hungry module. Many of the methods, ones
    > which are rarely used and can't be made memory efficient, will not be
    > implemented in the subclass.
    >
    > I could define subs in the subclass for each such method, invoking croak or
    > die so the call doesn't get dispatched up the @ISA list. But I want the
    > default to lie the other way around, methods are unimplemented unless other
    > specified.
    >
    > I guess I could walk the superclass's symbol table, automatically defining
    > a croaking sub for every subroutine in that symbol table unless they are in
    > my "implemented" list. But that seems rather hackish. Is there a better
    > way to do that?
    >
    > Other options would be to *not* put the superclass in @ISA, and manually
    > redispatch calls to the superclass when that is the proper thing to do,
    > with unimplemented ones getting exceptions from Perl rather than explicit
    > ones. Is there some pitfall in doing this?
    >
    > Or I could just do a complete code-fork and have the two modules completely
    > unrelated other than happening to have many method names in common. This
    > loses improvements made to the superclass. But since any new methods would
    > have to be manually inspected for compatibility before adding them to the
    > redispatch list anyway, I am not sure this is really a meaningful problem.
    >
    > Xho
    >


    This is similar to CGI::Simple, which replaces CGI with lighter weight
    code.
    It takes the approach of not using CGI at all.

    I guess it would depend on how much you wanted to call code from the
    original module. If it is very little, then probably better to make
    a clean break.

    --S
     
    smallpond, Aug 4, 2008
    #2
    1. Advertising

  3. Ben Morrow Guest

    Quoth :
    > I have a lot of scripts that use a memory-hungry module, but most of them
    > use only a small subset of that module's features, and it should be
    > possible to implement that subset in a more memory efficient way.
    >
    > I want to "subclass" the memory hungry module. Many of the methods, ones
    > which are rarely used and can't be made memory efficient, will not be
    > implemented in the subclass.


    A better idea, I would say, would be to make the split the other way:
    put the common, cheap methods in the superclass, and have the subclass
    inherit them and add more, expensive, methods. Of course, if the
    expensive class is not your code this is probably not possible.

    > I could define subs in the subclass for each such method, invoking croak or
    > die so the call doesn't get dispatched up the @ISA list. But I want the
    > default to lie the other way around, methods are unimplemented unless other
    > specified.
    >
    > I guess I could walk the superclass's symbol table, automatically defining
    > a croaking sub for every subroutine in that symbol table unless they are in
    > my "implemented" list. But that seems rather hackish. Is there a better
    > way to do that?


    That would be a bad idea. For one thing, you haven't considered methods
    the superclass inherits from elsewhere; for another, you haven't
    considered AUTOLOAD. Now, these may not be issues in your case, but if
    they become so you will get rather strange bugs.

    > Other options would be to *not* put the superclass in @ISA, and manually
    > redispatch calls to the superclass when that is the proper thing to do,
    > with unimplemented ones getting exceptions from Perl rather than explicit
    > ones. Is there some pitfall in doing this?


    Not really: it's called 'delegation', and is a perfectly respectable way
    of reusing code. You would need to keep around (or otherwise be able to
    produce on demand) an object of the expensive class, to invoke the
    methods on: once you've done that, you can use Class::HasA to perform
    the delegation automatically. It would probably be best to override
    ->isa to say that you *are*, in fact, a 'superclass'.

    You could also have something like

    sub AUTOLOAD {
    $_[0]->isa(__PACKAGE__)
    or croak "Undefined subroutine $AUTOLOAD called";

    (my $meth = $AUTOLOAD) =~ s/.*:://;

    if ($_[0]->_delegate->can($meth)) {
    croak "->$meth is not implemented in this light-weight version";
    }
    else {
    croak "Can't locate object method '$meth' via package " .
    __PACKAGE__;
    }
    }

    to distinguish methods you have chosen not to implement from methods
    that would never have existed.

    > Or I could just do a complete code-fork and have the two modules completely
    > unrelated other than happening to have many method names in common.


    This situation (two classes that don't inherit from each other, but have
    many methods with the same names and semantics) is what defines a
    'role': depending on how much time you want to put into this, you could
    look at some of the role-related modules on CPAN. The most complete, of
    course, is Moose, which provides a full Perl 6-ish object model for
    Perl 5; but it is both rather heavy and rather complicated to learn.

    Ben

    --
    I've seen things you people wouldn't believe: attack ships on fire off
    the shoulder of Orion; I watched C-beams glitter in the dark near the
    Tannhauser Gate. All these moments will be lost, in time, like tears in rain.
    Time to die.
     
    Ben Morrow, Aug 4, 2008
    #3
  4. brian d foy Guest

    In article <20080804125631.140$>, <>
    wrote:

    > I have a lot of scripts that use a memory-hungry module, but most of them
    > use only a small subset of that module's features, and it should be
    > possible to implement that subset in a more memory efficient way.
    >
    > I want to "subclass" the memory hungry module. Many of the methods, ones
    > which are rarely used and can't be made memory efficient, will not be
    > implemented in the subclass.


    Subclassing is probably the wrong technology here. Have you looked at
    using mixins or plugins? You separate the methods and features into
    functional groups in separate modules then only load the modules you
    need. They put their methods into the same namespace so you keep the
    same interface, but you don't load stuff you don't need.
     
    brian d foy, Aug 5, 2008
    #4
  5. Peter Scott Guest

    On Mon, 04 Aug 2008 16:56:29 +0000, xhoster wrote:
    > I have a lot of scripts that use a memory-hungry module, but most of them
    > use only a small subset of that module's features, and it should be
    > possible to implement that subset in a more memory efficient way.
    >
    > I want to "subclass" the memory hungry module. Many of the methods, ones
    > which are rarely used and can't be made memory efficient, will not be
    > implemented in the subclass.


    Sounds like a job for AutoSplit/AutoLoader.

    --
    Peter Scott
    http://www.perlmedic.com/
    http://www.perldebugged.com/
     
    Peter Scott, Aug 5, 2008
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Pritam Kamat

    Obfuscation and sub classing

    Pritam Kamat, Aug 8, 2003, in forum: Java
    Replies:
    2
    Views:
    527
    pete kirkham
    Aug 8, 2003
  2. Colin J. Williams

    Sub-classing NumArray - two questions

    Colin J. Williams, Oct 1, 2003, in forum: Python
    Replies:
    0
    Views:
    274
    Colin J. Williams
    Oct 1, 2003
  3. Bernard Lebel

    Problem with sub-classing

    Bernard Lebel, Jul 17, 2006, in forum: Python
    Replies:
    3
    Views:
    372
    Peter Otten
    Jul 17, 2006
  4. Colin J. Williams
    Replies:
    1
    Views:
    272
    Michael Amrhein
    Aug 15, 2007
  5. Colin J. Williams
    Replies:
    5
    Views:
    323
    Colin J. Williams
    Aug 17, 2007
Loading...

Share This Page