g0n has asked for the wisdom of the Perl Monks concerning the following question:

Fellow monks, I seek opinion.

I've written a custom module to automate deployment of some fairly complex config. My boss opined that it would be nice if the auto deployment was contained in a single file rather than a separate script and module. So I take my DataMethods.pm file and >> it onto the end of 'install.pl', then remove the 'use DataMethods' from the script part to see what happens. What happens is that everything works fine apart from inheritance. For example:

##############inheritest.pl####################### #use mammal; my $object = mammal::badger->new; print $object->hunt; print $object->snuffle; ############################################## package mammal; use vars qw(@ISA); sub new { my %object = ('blood'=>'warm'); return bless \%object; } sub snuffle { return "Snuffle"; } package mammal::badger; use vars qw(@ISA); @ISA = qw (mammal); sub new { my %object = ('stripes'=>'true'); return bless \%object; } sub hunt { return "for worms"; } 1;

This simple example script complains that method 'snuffle' doesn't exist, but runs method 'hunt' successfully.

I know this isn't exactly a normal approach to writing OO perl, but the effect is interesting. Anyone care to comment/set me right?

Perl version is 5.005_51 BTW

charles.

VGhpcyBtZXNzYWdlIGludGVudGlvbmFsbHkgcG9pbnRsZXNz

Replies are listed 'Best First'.
Re: object inheritance in non ~.pm files
by Mutant (Priest) on Jan 27, 2005 at 13:59 UTC
    I'm pretty sure this is solved by using "use base" instead of manually assigning to @ISA (but only because it also wraps it in a BEGIN).
      Thanks Mutant, your fix worked fine and was easy to implement. Thanks also to Dragonchild and Podmaster for suggestions.

      For reference, syntax for definition of subclass 'badger' should have been

      package mammal::badger; use base qw(mammal);

      No direct assignment to @ISA is necessary with this syntax.

      VGhpcyBtZXNzYWdlIGludGVudGlvbmFsbHkgcG9pbnRsZXNz
Re: object inheritance in non ~.pm files
by dragonchild (Archbishop) on Jan 27, 2005 at 13:51 UTC
    Change all the @ISA lines as so:
    package mammal::badger; use vars qw(@ISA); @ISA = qw (mammal); -------- package mammal::badger; BEGIN { @mammal::badger::ISA = qw (mammal); }

    Update: Added BEGIN{} around the @ISA assignment to fix mistake caught by PodMaster.

    Being right, does not endow the right to be rude; politeness costs nothing.
    Being unknowing, is not the same as being stupid.
    Expressing a contrary opinion, whether to the individual or the group, is more often a sign of deeper thought than of cantankerous belligerence.
    Do not mistake your goals as the only goals; your opinion as the only opinion; your confidence as correctness. Saying you know better is not the same as explaining you know better.

      And then clap your hands together because that doesn't solve the problem :)

      That assignment happens at runtime after $object is created, after hunt and snuffle methods are invoked.

      I would reccomend a BEGIN block, or even vars::i :)

       
      feeling kinda loopy

      MJD says "you can't just make shit up and expect the computer to know what you mean, retardo!"
      I run a Win32 PPM repository for perl 5.6.x and 5.8.x -- I take requests (README).
      ** The third rule of perl club is a statement of fact: pod is sexy.

Re: object inheritance in non ~.pm files
by Tanktalus (Canon) on Jan 27, 2005 at 14:26 UTC

    TMTOWTDI.

    Without BEGIN, without use base, just move your packages to the top of the file, then have "package main" to start your main code. Then everything happens in order.

Re: object inheritance in non ~.pm files
by ikegami (Patriarch) on Jan 27, 2005 at 15:32 UTC

    Something that wasn't mentioned is that mammal::new never gets called for badgers, incorrectly giving badgers cold blood. I presume you want to call it so that all mammals have blood=>'warm' (at least by default).

    ##############inheritest.pl####################### #use mammal; my $object = mammal::badger->new; print $object->hunt; print $object->snuffle; ############################################## package mammal; sub new { my ($class) = @_; my %object = ('blood'=>'warm'); return bless \%object, $class; # <-- Added $class } sub snuffle { return "Snuffle"; } ############################################## package mammal::badger; use vars qw(@ISA); BEGIN { @ISA = qw(mammal); } # <-- Solution to the asked question sub new { my ($class) = @_; my $self = $class->SUPER::new(); # <-- Base class creates obj $self->{'stripes'} = 'true'; # <-- Add badger specifics return $self;; } sub hunt { return "for worms"; } ############################################## 1;