OOP: Inheriting identically named methods

Discussion in 'Perl Misc' started by Tore Aursand, Feb 17, 2004.

  1. Tore Aursand

    Tore Aursand Guest

    Hmm. Don't know if I got the subject totally right. Just take a look at
    the example instead.

    I'm having problems with simple OOP inheritance. Seems like I've been
    away from the OOP business too long. I've read through perlboot, perltoot
    and perltooc.

    Here's some sample code:

    package Person;
    use strict;
    use warnings;

    sub new {
    my $class = shift;

    my $self = {
    'firstname' => '',
    'lastname' => '',
    'age' => 0,
    };
    bless( $self, $class );

    $self->_init( @_ );

    return $self;
    }

    sub _init {
    my $self = shift;
    my %ARGS = @_;

    $self->{'firstname'} = $ARGS{'firstname'} || '';
    $self->{'lastname'} = $ARGS{'lastname'} || '';
    $self->{'age'} = $ARGS{'age'} || 0;
    }

    1;

    package Employee;
    use strict;
    use warnings;

    use Person;
    our @ISA = qw( Person );

    sub new {
    my $class = shift;

    my $self = $class->SUPER::new( @_ );
    $self->{'salary'} = 0;
    bless( $self, $class );

    $self->_init( @_ );

    return $self;
    }

    sub _init {
    my $self = shift;
    my %ARGS = @_;

    $self->{'salary'} = $ARGS{'salary'} || 0;
    }

    1;

    This code may very well work as intended, but when I create a new instance
    of the Employee class, only Employee::_init() is run (and it is run twice);

    #!/usr/bin/perl
    #
    use strict;
    use warnings;

    use Employee;

    my $Employee = Employee->new();

    I really thought this would spawn into this:

    Employee::new()
    Person::new()
    Person::_init()
    Employee::_init()

    But it doesn't. Instead it is executed in this manner:

    Employee::new()
    Person::new()
    Employee::_init()
    Employee::_init()

    Anyone care to explain what's going on and what I need to do in order to
    make this work as I want it to?

    Thanks!


    --
    Tore Aursand <>
    "What we see depends mainly on what we look for." -- Sir John Lubbock
     
    Tore Aursand, Feb 17, 2004
    #1
    1. Advertising

  2. Tore Aursand

    Ben Morrow Guest

    Tore Aursand <> wrote:
    > Hmm. Don't know if I got the subject totally right. Just take a look at
    > the example instead.
    >
    > I'm having problems with simple OOP inheritance. Seems like I've been
    > away from the OOP business too long. I've read through perlboot, perltoot
    > and perltooc.
    >
    > Here's some sample code:
    >
    > package Person;
    > use strict;
    > use warnings;
    >
    > sub new {
    > my $class = shift;
    >
    > my $self = {
    > 'firstname' => '',
    > 'lastname' => '',
    > 'age' => 0,


    You don't need to do this as you init them all in _init. You can just
    say
    my $self = bless {}, $class;

    > };
    > bless( $self, $class );
    >
    > $self->_init( @_ );


    If $self is actually an Employee object, this will call Employee::_init.

    > return $self;
    > }
    >
    > sub _init {
    > my $self = shift;
    > my %ARGS = @_;
    >
    > $self->{'firstname'} = $ARGS{'firstname'} || '';
    > $self->{'lastname'} = $ARGS{'lastname'} || '';
    > $self->{'age'} = $ARGS{'age'} || 0;


    None of the hash keys need quoting.

    > }
    >
    > 1;
    >
    > package Employee;
    > use strict;
    > use warnings;
    >
    > use Person;
    > our @ISA = qw( Person );


    Better than these two lines is
    use base qw/Person/;
    as it happens at compile time.

    > sub new {
    > my $class = shift;
    >
    > my $self = $class->SUPER::new( @_ );
    > $self->{'salary'} = 0;


    This, again, is done by _init.

    > bless( $self, $class );
    >
    > $self->_init( @_ );


    These have already been done by Person::new (that's why you used two-arg
    bless, remember :).

    > return $self;
    > }
    >
    > sub _init {
    > my $self = shift;
    > my %ARGS = @_;


    Here you want to call $self->SUPER::_init(@_), so that Person::_init
    gets called. You probably also want to make the _init methods remove the
    keys they know and return the rest:

    $self->{salary} = (delete $ARGS{salary}) || 0;

    return %ARGS;

    and then in subclasses you can say

    my %ARGS = $self->SUPER::_init(@_);

    to let the superclass handle the keys it knows and return you the rest.

    > $self->{'salary'} = $ARGS{'salary'} || 0;
    > }
    >
    > 1;


    Ben

    --
    Although few may originate a policy, we are all able to judge it.
    - Pericles of Athens, c.430 B.C.
     
    Ben Morrow, Feb 17, 2004
    #2
    1. Advertising

  3. Tore Aursand

    Tore Aursand Guest

    On Tue, 17 Feb 2004 12:20:16 +0000, Ben Morrow wrote:
    >> package Person;
    >> use strict;
    >> use warnings;
    >>
    >> sub new {
    >> my $class = shift;
    >>
    >> my $self = {
    >> 'firstname' => '',
    >> 'lastname' => '',
    >> 'age' => 0,


    > You don't need to do this as you init them all in _init. You can just
    > say
    > my $self = bless {}, $class;


    I see that as pretty irrelevant to my problem, and I _want_ to do it this
    way. That way I can handle all the initialisation of the object inside a
    special method, while the structure of the class in another.

    Why? Well. Consider this _init() method;

    sub _init {
    my $self = shift;
    my %ARGS = @_;

    foreach ( keys %ARGS ) {
    if ( exists $self->{$_} ) {
    $self->{$_} = $ARGS{$_};
    }
    else {
    warn "'$_' isn't a member of this class\n";
    }
    }
    }

    Easier to read the code, IMO; new() takes care of the class definition,
    while _init() initialises it.

    >> $self->{'firstname'} = $ARGS{'firstname'} || '';
    >> $self->{'lastname'} = $ARGS{'lastname'} || ''; $self->{'age'}


    > None of the hash keys need quoting.


    I know, but that's not a problem. I helps me from going cross-eyed; my
    editor highlights those strings so nice. :)

    >> package Employee;
    >> use strict;
    >> use warnings;
    >>
    >> use Person;
    >> our @ISA = qw( Person );


    > Better than these two lines is
    > use base qw/Person/;
    > as it happens at compile time.


    Nice to know. What is the difference between these two methods? Are they
    practically identical? Should one never need to use @ISA? (No, I haven't
    read the 'perldoc base' yet, but I will do after writing this post). :)

    >> bless( $self, $class );
    >>
    >> $self->_init( @_ );


    > These have already been done by Person::new (that's why you used two-arg
    > bless, remember :).


    Aha. So I should never bless() an inherited class?

    Just to sum up. Does this look better (forget about where I initialise
    the data and how I quote, please)?

    package Person;
    use strict;
    use warnings;

    sub new {
    my $class = shift;

    my $self = {
    'firstname' => '',
    'lastname' => '',
    'age' => 0,
    };
    bless( $self, $class );

    $self->_init( @_ );

    return $self;
    }

    sub _init {
    my $self = shift;
    }

    1;

    package Employee;
    use strict;
    use warnings;

    use Person;
    our @ISA = qw( Person );

    sub new {
    my $class = shift;

    my $self = $class->SUPER::new( @_ );
    $self->{'salary'} = 0;

    return $self;
    }

    sub _init {
    my $self = shift;

    $self->SUPER::_init( @_ );
    }

    1;

    I'm still using the @ISA, but this will - of course - be changed whenever
    I find it suitable, as it didn't seem to do any difference in my example
    above. :)


    --
    Tore Aursand <>
    "Omit needless words. Vigorous writing is concise. A sentence should
    contain no unnecessary words, a paragraph no unnecessary sentences,
    for the same reason that a drawing should have no unnecessary lines
    and a machine no unnecessary parts." -- William Strunk Jr.
     
    Tore Aursand, Feb 17, 2004
    #3
    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.  opalinski from opalpaweb
    Replies:
    9
    Views:
    2,654
    opalinski from opalpaweb
    Mar 1, 2006
  2. Stanimir Stamenkov
    Replies:
    9
    Views:
    1,051
    David Carlisle
    Jan 26, 2005
  3. Joris Gillis
    Replies:
    9
    Views:
    422
    Jan Roland Eriksson
    Jan 8, 2005
  4. Spoon
    Replies:
    2
    Views:
    331
    Rahul
    Dec 20, 2007
  5. Simon Strandgaard

    compare two identically hashes fails

    Simon Strandgaard, Oct 6, 2003, in forum: Ruby
    Replies:
    6
    Views:
    155
    Kent Dahl
    Oct 6, 2003
Loading...

Share This Page