Reference overloading helps inheritance

Discussion in 'Perl Misc' started by Anno Siegel, Feb 7, 2004.

  1. Anno Siegel

    Anno Siegel Guest

    Inheritance in Perl OO has its difficulties when it comes to data
    encapsulation. Basically, it can't be done without a peek at the
    implementation of the superclass.

    A frequent situation is that the inheriting class contains an object
    of the superclass (or, more generally, has a method that returns a
    superclass object), and you want it to respond to the methods of the
    superclass. But let me use a concrete example, the generalization
    will be obvious.

    Consider a class "Tape", whose objects are conceptually snapshots of
    some files or directories at a given time (not necessarily on magnetic
    tape, but that's a nice short name). The implementation is a basic
    hash-as-a-record:

    bless {
    name => $name,
    ...
    time => Time::piece( ...),
    }, Tape;

    sub name { $_[ 0]->{ name} }
    sub time { $_[ 0]->{ time} }

    Now I want Tape to respond to the methods of Time::piece, that is, I
    want to put "Time::piece" on @Tape::ISA. (Because of the overloading
    Time::piece does, this means I can compare tapes with each other, or
    with other dates (Time::piece objects) to see which is older. Handy
    when deciding which tape to overwrite.)

    One way of doing this is through Tape::AUTOLOAD. That can be considered
    standard, I won't go into the possible variants here.

    Instead of AUTOLOAD one can also use overload, which was new to me.
    A peek at the implementation of Time::piece shows that the objects
    are array-refs. So, if we can make Time::piece think that Tape objects
    are the right kind of array ref, we're done. But that is what overloading
    "@{}" does. So, in package Tape, saying

    use base qw( Time::piece);
    use overload ( '@{}' => 'time' );

    is all that's needed to make Tape objects inherit from Time::piece.
    That's pretty minimal.

    The method isn't entirely clean, but some methods that are described
    in Perl's OO recommendations are less so. It relies on the fact that
    the superclass uses a particular (overloadable) data type for its
    implementation, but on none of the further details. Obviously, it also
    occupies that particular reference overloading, so if you need that
    for something else, you're out of luck.

    The implementation also assumes that the inherited data type is different
    from the data type of the inheriting class. Otherwise, overloading
    your own data type is still do-able, but a little involved. This
    restriction can be worked around by yielding and making your data type
    something else (wrap a scalar ref around it, for instance), but that
    makes the method less attractive.

    I'm surely not the first to make the observation that overloading can
    help inheritance in this way, but since I didn't know about it, I
    conclude that it isn't "well known" and deserves a mention :)

    Anno
     
    Anno Siegel, Feb 7, 2004
    #1
    1. Advertising

  2. Anno Siegel

    Uri Guttman Guest

    >>>>> "AS" == Anno Siegel <-berlin.de> writes:

    AS> Inheritance in Perl OO has its difficulties when it comes to data
    AS> encapsulation. Basically, it can't be done without a peek at the
    AS> implementation of the superclass.

    some modules will do this for you. see the class:: modules by damian conway.

    AS> A frequent situation is that the inheriting class contains an object
    AS> of the superclass (or, more generally, has a method that returns a
    AS> superclass object), and you want it to respond to the methods of the
    AS> superclass. But let me use a concrete example, the generalization
    AS> will be obvious.


    AS> Now I want Tape to respond to the methods of Time::piece, that is, I
    AS> want to put "Time::piece" on @Tape::ISA. (Because of the overloading
    AS> Time::piece does, this means I can compare tapes with each other, or
    AS> with other dates (Time::piece objects) to see which is older. Handy
    AS> when deciding which tape to overwrite.)

    this is done by damian's class::delegate module. it can make methods in
    the owner (the object that has the other object) that call through to
    the owned object.

    uri

    --
    Uri Guttman ------ -------- http://www.stemsystems.com
    --Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
    Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
     
    Uri Guttman, Feb 7, 2004
    #2
    1. Advertising

  3. Anno Siegel

    Anno Siegel Guest

    Uri Guttman <> wrote in comp.lang.perl.misc:
    > >>>>> "AS" == Anno Siegel <-berlin.de> writes:

    >
    > AS> Inheritance in Perl OO has its difficulties when it comes to data
    > AS> encapsulation. Basically, it can't be done without a peek at the
    > AS> implementation of the superclass.
    >
    > some modules will do this for you. see the class:: modules by damian conway.
    >
    > AS> A frequent situation is that the inheriting class contains an object
    > AS> of the superclass (or, more generally, has a method that returns a
    > AS> superclass object), and you want it to respond to the methods of the
    > AS> superclass. But let me use a concrete example, the generalization
    > AS> will be obvious.
    >
    > AS> Now I want Tape to respond to the methods of Time::piece, that is, I
    > AS> want to put "Time::piece" on @Tape::ISA. (Because of the overloading
    > AS> Time::piece does, this means I can compare tapes with each other, or
    > AS> with other dates (Time::piece objects) to see which is older. Handy
    > AS> when deciding which tape to overwrite.)
    >
    > this is done by damian's class::delegate module. it can make methods in
    > the owner (the object that has the other object) that call through to
    > the owned object.


    Yes, it does, and it does a lot more than "my" method, and also some less
    (it only works with hash objects). It uses the time-honored AUTOLOAD
    to do run-time delegation, with its own method-caching and more. BTW,
    the author seems to be Kurt Starsinic, not Damian.

    However, the point of my posting was to show how to make Perl's native
    inheritance (through @ISA) work if your object happens to contain (or
    otherwise create) a superclass object. The point is that you can turn
    an existing HAS-A relation into a working inheritance relation in two
    statements (if applicable). It is a method that an OO programmer in
    Perl should know about. That some modules do a more profound job (like
    establishing the HAS-A relation in the first place), is irrelevant.

    Anno
     
    Anno Siegel, Feb 7, 2004
    #3
  4. Anno Siegel

    Anno Siegel Guest

    Uri Guttman <> wrote in comp.lang.perl.misc:
    > >>>>> "AS" == Anno Siegel <-berlin.de> writes:

    >
    > AS> Inheritance in Perl OO has its difficulties when it comes to data
    > AS> encapsulation. Basically, it can't be done without a peek at the
    > AS> implementation of the superclass.
    >
    > some modules will do this for you. see the class:: modules by damian conway.
    >
    > AS> A frequent situation is that the inheriting class contains an object
    > AS> of the superclass (or, more generally, has a method that returns a
    > AS> superclass object), and you want it to respond to the methods of the
    > AS> superclass. But let me use a concrete example, the generalization
    > AS> will be obvious.
    >
    > AS> Now I want Tape to respond to the methods of Time::piece, that is, I
    > AS> want to put "Time::piece" on @Tape::ISA. (Because of the overloading
    > AS> Time::piece does, this means I can compare tapes with each other, or
    > AS> with other dates (Time::piece objects) to see which is older. Handy
    > AS> when deciding which tape to overwrite.)
    >
    > this is done by damian's class::delegate module. it can make methods in
    > the owner (the object that has the other object) that call through to
    > the owned object.


    Yes, it does, and it does a lot more than "my" method, and also some less
    (it only works with hash objects). It uses the time-honored AUTOLOAD
    to do run-time delegation, with its own method-caching and more. BTW,
    the author seems to be Kurt Starsinic, not Damian.

    However, the point of my posting was to show how to make Perl's native
    inheritance (through @ISA) work if your object happens to contain (or
    otherwise create) a superclass object. The point is that you can turn
    an existing HAS-A relation into a working inheritance relation in two
    statements (if applicable). It is a method that an OO programmer in
    Perl should know about. That some modules do a more profound job (like
    establishing the HAS-A relation in the first place), is irrelevant.

    Anno
     
    Anno Siegel, Feb 7, 2004
    #4
  5. Anno Siegel

    Uri Guttman Guest

    >>>>> "AS" == Anno Siegel <-berlin.de> writes:

    AS> Uri Guttman <> wrote in comp.lang.perl.misc:

    >> this is done by damian's class::delegate module. it can make methods in
    >> the owner (the object that has the other object) that call through to
    >> the owned object.


    AS> Yes, it does, and it does a lot more than "my" method, and also some less
    AS> (it only works with hash objects). It uses the time-honored AUTOLOAD
    AS> to do run-time delegation, with its own method-caching and more. BTW,
    AS> the author seems to be Kurt Starsinic, not Damian.

    i am farily sure damian wrote it originally and gave it to kurt to
    maintain. he has done that with a bunch of his modules. he doesn't have
    the time to maintain all of them once he has created them.

    AS> However, the point of my posting was to show how to make Perl's
    AS> native inheritance (through @ISA) work if your object happens to
    AS> contain (or otherwise create) a superclass object. The point is
    AS> that you can turn an existing HAS-A relation into a working
    AS> inheritance relation in two statements (if applicable). It is a
    AS> method that an OO programmer in Perl should know about. That some
    AS> modules do a more profound job (like establishing the HAS-A
    AS> relation in the first place), is irrelevant.

    i like HAS-A more than ISA and use it a fair amount but i don't always
    do direct delegation. i will take another peek at your stuff and see if
    it is worth stealing. one side issue it that overloading is slower AFAIK
    (like tying is very slow we know).

    uri

    --
    Uri Guttman ------ -------- http://www.stemsystems.com
    --Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
    Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
     
    Uri Guttman, Feb 7, 2004
    #5
  6. Anno Siegel

    Anno Siegel Guest

    Uri Guttman <> wrote in comp.lang.perl.misc:
    > >>>>> "AS" == Anno Siegel <-berlin.de> writes:


    > AS> However, the point of my posting was to show how to make Perl's
    > AS> native inheritance (through @ISA) work if your object happens to
    > AS> contain (or otherwise create) a superclass object. The point is
    > AS> that you can turn an existing HAS-A relation into a working
    > AS> inheritance relation in two statements (if applicable). It is a
    > AS> method that an OO programmer in Perl should know about. That some
    > AS> modules do a more profound job (like establishing the HAS-A
    > AS> relation in the first place), is irrelevant.
    >
    > i like HAS-A more than ISA and use it a fair amount but i don't always
    > do direct delegation. i will take another peek at your stuff and see if
    > it is worth stealing. one side issue it that overloading is slower AFAIK
    > (like tying is very slow we know).


    Overloading is slightly slower than a plain method call (about a third is
    what I benchmarked, though these small differences are hard to measure).
    That's no way near the loss you deal with in a typical tie.

    Anno
     
    Anno Siegel, Feb 8, 2004
    #6
  7. Anno Siegel

    Anno Siegel Guest

    Uri Guttman <> wrote in comp.lang.perl.misc:
    > >>>>> "AS" == Anno Siegel <-berlin.de> writes:


    > AS> However, the point of my posting was to show how to make Perl's
    > AS> native inheritance (through @ISA) work if your object happens to
    > AS> contain (or otherwise create) a superclass object. The point is
    > AS> that you can turn an existing HAS-A relation into a working
    > AS> inheritance relation in two statements (if applicable). It is a
    > AS> method that an OO programmer in Perl should know about. That some
    > AS> modules do a more profound job (like establishing the HAS-A
    > AS> relation in the first place), is irrelevant.
    >
    > i like HAS-A more than ISA and use it a fair amount but i don't always
    > do direct delegation. i will take another peek at your stuff and see if
    > it is worth stealing. one side issue it that overloading is slower AFAIK
    > (like tying is very slow we know).


    Overloading is slightly slower than a plain method call (about a third is
    what I benchmarked, though these small differences are hard to measure).
    That's nowhere near the loss you deal with in a typical tie.

    Anno
     
    Anno Siegel, Feb 8, 2004
    #7
    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. Oliver
    Replies:
    2
    Views:
    1,089
    Imran Koradia
    Nov 22, 2004
  2. =?Utf-8?B?RWR3YXJkIFNtaXQ=?=
    Replies:
    1
    Views:
    315
    =?Utf-8?B?RWR3YXJkIFNtaXQ=?=
    May 21, 2004
  3. Enes Kabacaoglu

    NEWBIE needs helps about creating links

    Enes Kabacaoglu, Dec 25, 2005, in forum: ASP .Net
    Replies:
    1
    Views:
    340
    Nathan Sokalski
    Dec 30, 2005
  4. cppsks
    Replies:
    0
    Views:
    827
    cppsks
    Oct 27, 2004
  5. Bengt Richter
    Replies:
    0
    Views:
    296
    Bengt Richter
    Aug 7, 2003
Loading...

Share This Page