New to Perl, OOP inheritance

Discussion in 'Perl Misc' started by Peter Michaux, Feb 16, 2007.

  1. Hi,

    I'm new to Perl (from C, JavaScript, Ruby) and going through the Camel
    book.

    Below is my an example of trying to write Ruby/Java style class-based
    inheritance in Perl. (In JavaScript, Ruby and Java I would write like
    this <URL: http://peter.michaux.ca/article/1>) The first eight lines
    of each new subroutine below seems quite clunky. I'm trying to make it
    so the new can be called either to instantiate a new object or be
    called as super from a child class's constructor. I only want to name
    the parent class once in the @ISA and use SUPER everywhere else so I
    can change the inheritance chain easily.

    package Person;

    sub new {
    my $invocant = shift;
    my $this;
    if (ref($invocant)) {
    $this = $invocant;
    } else {
    $this = {};
    bless($this, $invocant);
    }
    my ($name) = @_;
    $this->{name} = $name;
    return $this;
    }

    sub toString {
    $this = shift;
    return $this->{name};
    }

    # ---------------------------------------------

    package Employee;
    our @ISA = ('Person');

    sub new {
    my $invocant = shift;
    my $this;
    if (ref($invocant)) {
    $this = $invocant;
    } else {
    $this = {};
    bless($this, $invocant);
    }
    my ($name, $id) = @_;

    $this->SUPER::new($name);
    $this->{id} = $id;
    return $this;
    }

    sub toString {
    my $this = shift;
    return $this->SUPER::toString() . ': ' . $this->{id};
    }

    # ---------------------------------------------

    $ted = Employee->new('Ted', 10);
    print ($ted->toString(), "\n");


    Any suggestions to clean up the clunky parts of the new subroutines? I
    expect that some will say "this is not how you do OOP Inheritance in
    Perl." Other options?

    Thank you,
    Peter
    http://peter.michaux.ca
    http://forkjavascript.org
     
    Peter Michaux, Feb 16, 2007
    #1
    1. Advertising

  2. Peter Michaux

    -berlin.de Guest

    Peter Michaux <> wrote in comp.lang.perl.misc:
    > Hi,
    >
    > I'm new to Perl (from C, JavaScript, Ruby) and going through the Camel
    > book.
    >
    > Below is my an example of trying to write Ruby/Java style class-based
    > inheritance in Perl. (In JavaScript, Ruby and Java I would write like
    > this <URL: http://peter.michaux.ca/article/1>) The first eight lines
    > of each new subroutine below seems quite clunky. I'm trying to make it
    > so the new can be called either to instantiate a new object or be
    > called as super from a child class's constructor. I only want to name
    > the parent class once in the @ISA and use SUPER everywhere else so I
    > can change the inheritance chain easily.


    So if ->new is called as an object method it (re-)initializes the
    object. That's a reasonable approach, though it might be clearer
    to have separate methods (object method ->init, class method ->new)
    for that.

    > package Person;
    >
    > sub new {
    > my $invocant = shift;
    > my $this;
    > if (ref($invocant)) {
    > $this = $invocant;
    > } else {
    > $this = {};
    > bless($this, $invocant);
    > }
    > my ($name) = @_;
    > $this->{name} = $name;
    > return $this;
    > }
    >
    > sub toString {
    > $this = shift;
    > return $this->{name};
    > }
    >
    > # ---------------------------------------------
    >
    > package Employee;
    > our @ISA = ('Person');
    >
    > sub new {
    > my $invocant = shift;
    > my $this;
    > if (ref($invocant)) {
    > $this = $invocant;
    > } else {
    > $this = {};
    > bless($this, $invocant);
    > }
    > my ($name, $id) = @_;
    >
    > $this->SUPER::new($name);
    > $this->{id} = $id;
    > return $this;
    > }
    >
    > sub toString {
    > my $this = shift;
    > return $this->SUPER::toString() . ': ' . $this->{id};
    > }
    >
    > # ---------------------------------------------
    >
    > $ted = Employee->new('Ted', 10);
    > print ($ted->toString(), "\n");
    >
    >
    > Any suggestions to clean up the clunky parts of the new subroutines? I
    > expect that some will say "this is not how you do OOP Inheritance in
    > Perl." Other options?


    You can pack most of the "clunky part" in one statement:

    sub new {
    my $invocant = shift;
    my $this = ref( $invocant) ? $invocant : bless {}, $invocant;
    my ($name) = @_;
    # ...
    }

    Anno
     
    -berlin.de, Feb 16, 2007
    #2
    1. Advertising

  3. On Feb 16, 1:06 am, -berlin.de wrote:
    > Peter Michaux <> wrote in comp.lang.perl.misc:
    >
    > > Hi,

    >
    > > I'm new to Perl (from C, JavaScript, Ruby) and going through the Camel
    > > book.

    >
    > > Below is my an example of trying to write Ruby/Java style class-based
    > > inheritance in Perl. (In JavaScript, Ruby and Java I would write like
    > > this <URL:http://peter.michaux.ca/article/1>) The first eight lines
    > > of each new subroutine below seems quite clunky. I'm trying to make it
    > > so the new can be called either to instantiate a new object or be
    > > called as super from a child class's constructor. I only want to name
    > > the parent class once in the @ISA and use SUPER everywhere else so I
    > > can change the inheritance chain easily.

    >
    > So if ->new is called as an object method it (re-)initializes the
    > object. That's a reasonable approach, though it might be clearer
    > to have separate methods (object method ->init, class method ->new)
    > for that.
    >
    >
    >
    > > package Person;

    >
    > > sub new {
    > > my $invocant = shift;
    > > my $this;
    > > if (ref($invocant)) {
    > > $this = $invocant;
    > > } else {
    > > $this = {};
    > > bless($this, $invocant);
    > > }
    > > my ($name) = @_;
    > > $this->{name} = $name;
    > > return $this;
    > > }

    >
    > > sub toString {
    > > $this = shift;
    > > return $this->{name};
    > > }

    >
    > > # ---------------------------------------------

    >
    > > package Employee;
    > > our @ISA = ('Person');

    >
    > > sub new {
    > > my $invocant = shift;
    > > my $this;
    > > if (ref($invocant)) {
    > > $this = $invocant;
    > > } else {
    > > $this = {};
    > > bless($this, $invocant);
    > > }
    > > my ($name, $id) = @_;

    >
    > > $this->SUPER::new($name);
    > > $this->{id} = $id;
    > > return $this;
    > > }

    >
    > > sub toString {
    > > my $this = shift;
    > > return $this->SUPER::toString() . ': ' . $this->{id};
    > > }

    >
    > > # ---------------------------------------------

    >
    > > $ted = Employee->new('Ted', 10);
    > > print ($ted->toString(), "\n");

    >
    > > Any suggestions to clean up the clunky parts of the new subroutines? I
    > > expect that some will say "this is not how you do OOP Inheritance in
    > > Perl." Other options?

    >
    > You can pack most of the "clunky part" in one statement:
    >
    > sub new {
    > my $invocant = shift;
    > my $this = ref( $invocant) ? $invocant : bless {}, $invocant;
    > my ($name) = @_;
    > # ...
    > }
    >
    > Anno



    Thanks for the reply. Good to know I wasn't way out in left field.

    Peter
     
    Peter Michaux, Feb 16, 2007
    #3
  4. Peter Michaux

    -berlin.de Guest

    Peter Michaux <> wrote in comp.lang.perl.misc:
    > On Feb 16, 1:06 am, -berlin.de wrote:
    > > Peter Michaux <> wrote in comp.lang.perl.misc:
    > >
    > > > Hi,

    > >
    > > > I'm new to Perl (from C, JavaScript, Ruby) and going through the Camel
    > > > book.


    [...]

    > > So if ->new is called as an object method it (re-)initializes the
    > > object. That's a reasonable approach, though it might be clearer
    > > to have separate methods (object method ->init, class method ->new)
    > > for that.


    [...]

    > > > Any suggestions to clean up the clunky parts of the new subroutines? I
    > > > expect that some will say "this is not how you do OOP Inheritance in
    > > > Perl." Other options?

    > >
    > > You can pack most of the "clunky part" in one statement:
    > >
    > > sub new {
    > > my $invocant = shift;
    > > my $this = ref( $invocant) ? $invocant : bless {}, $invocant;
    > > my ($name) = @_;
    > > # ...
    > > }
    > >
    > > Anno

    >
    >
    > Thanks for the reply. Good to know I wasn't way out in left field.


    Let me take the occasion and add a few more general remarks.

    It is a good thing for a class to have not only a creator but also
    a separate initializer. This aspect has been sadly neglected by
    the Perl OO community. If creation and initialization are coupled,
    you're in trouble with multiple inheritance. You can create an
    object only once, but you must (potentially) initialize it for
    every class it inherits from. Perl classes traditionally come
    with only a creator, neglecting that simple arithmetic.

    Your approach to have ->new behave like an initializer if called
    on an object is one way to provide separate initialization. The
    semantics could be expressed as "set this object up according to
    the arguments as if it were new", which is reasonable enough.

    Unfortunately, a large strain of Perl classes has emerged whose
    ->new methods show an entirely different behavior when called as
    an object method. The done thing is (was? it seems to be declining)
    to derive a class from the object via the attractive idiom

    my $class = ref( $invocant) || $invocant;

    ....and plough ahead creating a new object, no matter what. In
    the rare situations where that behavior is useful, I find it
    clearer to express it on the client level as

    my $like_the_other = ref( $obj)->new( ...);

    I don't remember ever wanting that except in some cross-class
    overloading situations. The need for separate initialization
    comes up regularly with multiple inheritance, so the behavior
    you suggest is far more useful. It is perhaps no coincidence
    that you spontaneously came up with it. It appears you are
    familiar with OO in general, but not with the particular quirks
    of Perl's OO culture.

    Anno
     
    -berlin.de, Feb 17, 2007
    #4
  5. Hi Anno,

    On Feb 16, 5:18 pm, -berlin.de wrote:

    <snip>

    > Unfortunately, a large strain of Perl classes has emerged whose
    > ->new methods show an entirely different behavior when called as
    > an object method. The done thing is (was? it seems to be declining)
    > to derive a class from the object via the attractive idiom
    >
    > my $class = ref( $invocant) || $invocant;
    >
    > ...and plough ahead creating a new object, no matter what.


    I read this style in the Camel book at did a complete double take. I
    haven't encountered a situation where I'd want to do that. Then again
    I haven't had that possibility available before so haven't thought
    about what efficiency it allows.

    > In
    > the rare situations where that behavior is useful, I find it
    > clearer to express it on the client level as
    >
    > my $like_the_other = ref( $obj)->new( ...);


    I think this is much nicer and makes the Perl OOP system more like
    other OOP languages. Not that Perl should be written like other
    languages but if developers like me are showing up into some Perl
    scripts it will make more sense.

    > I don't remember ever wanting that except in some cross-class
    > overloading situations. The need for separate initialization
    > comes up regularly with multiple inheritance, so the behavior
    > you suggest is far more useful. It is perhaps no coincidence
    > that you spontaneously came up with it. It appears you are
    > familiar with OO in general, but not with the particular quirks
    > of Perl's OO culture.


    I think I'm a little spoiled coming from Ruby which built on Perl's
    successes. The Perl quirks I've read so far have been interesting :)

    Thanks again,
    Peter
     
    Peter Michaux, Feb 17, 2007
    #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. Leslie Viljoen

    Easy OOP with Perl

    Leslie Viljoen, Feb 21, 2005, in forum: Perl
    Replies:
    0
    Views:
    526
    Leslie Viljoen
    Feb 21, 2005
  2. cppsks
    Replies:
    0
    Views:
    833
    cppsks
    Oct 27, 2004
  3. a
    Replies:
    6
    Views:
    384
    James Kanze
    Jun 26, 2007
  4. Replies:
    9
    Views:
    173
    John Wilger
    Mar 16, 2007
  5. kj
    Replies:
    3
    Views:
    115
    James Willmore
    May 14, 2004
Loading...

Share This Page