Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > New to Perl, OOP inheritance

Reply
Thread Tools

New to Perl, OOP inheritance

 
 
Peter Michaux
Guest
Posts: n/a
 
      02-16-2007
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

 
Reply With Quote
 
 
 
 
anno4000@radom.zrz.tu-berlin.de
Guest
Posts: n/a
 
      02-16-2007
Peter Michaux <(E-Mail Removed)> 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
 
Reply With Quote
 
 
 
 
Peter Michaux
Guest
Posts: n/a
 
      02-16-2007
On Feb 16, 1:06 am, (E-Mail Removed)-berlin.de wrote:
> Peter Michaux <(E-Mail Removed)> 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

 
Reply With Quote
 
anno4000@radom.zrz.tu-berlin.de
Guest
Posts: n/a
 
      02-17-2007
Peter Michaux <(E-Mail Removed)> wrote in comp.lang.perl.misc:
> On Feb 16, 1:06 am, (E-Mail Removed)-berlin.de wrote:
> > Peter Michaux <(E-Mail Removed)> 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
 
Reply With Quote
 
Peter Michaux
Guest
Posts: n/a
 
      02-17-2007
Hi Anno,

On Feb 16, 5:18 pm, (E-Mail Removed)-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

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Private Inheritance and Publice Inheritance karthikbalaguru C++ 9 09-10-2007 01:05 PM
oop inheritance graph a C++ 6 06-26-2007 09:29 AM
General Ruby OOP Question - using inheritance or include for shared attributes james.d.masters@gmail.com Ruby 9 03-16-2007 01:59 AM
mul. inheritance & overloading operator new/delete solved by virtual base inheritance? cppsks C++ 0 10-27-2004 07:49 PM
Private access modifier and Inheritance (Inheritance implementation in Java) maxw_cc Java 1 12-21-2003 11:38 AM



Advertisments