Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
PerlMonks  

Re: Variables in Common parent class

by Athanasius (Monsignor)
on Mar 10, 2013 at 03:58 UTC ( #1022642=note: print w/ replies, xml ) Need Help??


in reply to Variables in Common parent class

Some problems with the code shown:

  • $self is a class variable, it should be an object (instance) variable.
  • Subroutines have unneccessary prototypes.
  • use strict and use warnings are missing.
  • Module names should be capitalised.

But the main problem is the structural relationship of the child classes to the parent class. Here is one way to do what is wanted:

#! perl use strict; use warnings; #--------------------------------------------------------------------- +--------- { package SuperModule; sub new { my ($class, %params) = @_; my $self = { dbh => $params{DB} }; return bless $self, $class; } sub print_super { my ($self) = @_; print 'Super module: ', $self->{dbh}, "\n"; } } #--------------------------------------------------------------------- +--------- { package MyModule; our @ISA = qw( SuperModule ); sub new { my ($class, %params) = @_; my $self = SuperModule::new($class, %params); $self->{file_name} = $params{'file name'}; return bless $self, $class; } sub print_file { my ($self) = @_; print 'My file name from file obj ', $self->{file_name}, "\n"; } } #--------------------------------------------------------------------- +--------- { package YourModule; our @ISA = qw( SuperModule ); sub new { my ($class, %params) = @_; my $self = SuperModule::new($class, %params); $self->{block_name} = $params{'block name'}; return bless $self, $class; } sub print_block { my ($self) = @_; print 'My block name from block obj ', $self->{block_name}, "\ +n"; } } #--------------------------------------------------------------------- +--------- my %f_params = ( DB => 'File DB value', 'file name' => 'Lisa', ); my %b_params = ( DB => 'Block DB value', 'block name' => 'Pisa', ); my $file_obj = MyModule ->new(%f_params); my $block_obj = YourModule->new(%b_params); $file_obj ->print_super(); $file_obj ->print_file(); $block_obj->print_super(); $block_obj->print_block();

Output:

13:56 >perl 567_SoPW.pl Super module: File DB value My file name from file obj Lisa Super module: Block DB value My block name from block obj Pisa 13:56 >

Hope that helps,

Update: ++tobyink, below, for the improvements to the child class constructors.

Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,


Comment on Re: Variables in Common parent class
Select or Download Code
Re^2: Variables in Common parent class
by tobyink (Abbot) on Mar 10, 2013 at 06:34 UTC

    All generally good advice, but for the constructors in the children, I'd prefer:

    sub new { my ($class, %params) = @_; my $self = $class->SUPER::new(%params); $self->{block_name} = $params{'block name'}; return $self; }

    This ensures that the parent constructor is called as a method (and thus obeys inheritance).

    There's no need to re-bless $self.

    package Cow { use Moo; has name => (is => 'lazy', default => sub { 'Mooington' }) } say Cow->new->name
Re^2: Variables in Common parent class
by perlbaski (Acolyte) on Mar 11, 2013 at 02:44 UTC
    Thanks! But one further question, why is there a dereferncing(->) operator while calling new on MyModule and scope resolution operator while calling new on SuperModule.

      With the scope resolution operator, you get a normal subroutine call. But with the dereferencing operator, you get a method call in which the name of the class is passed implicitly as the first argument. So

      Foo::bar(1, 2, 3);

      calls sub bar in the Foo package and passes 1, 2, 3 as the arguments (which are aliased in @_). But

      Foo->bar(1, 2, 3);

      calls Foo::bar with the arguments Foo, 1, 2, 3. Likewise, if $obj is of class Foo, then

      $obj->bar(1, 2, 3);

      calls Foo::bar with the arguments Foo, 1, 2, 3.

      See Methods in perlootut and Method Invocation in perlobj.

      Hope that helps,

      Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

Reaped: Re^2: Variables in Common parent class
by NodeReaper (Curate) on Mar 11, 2013 at 02:44 UTC
Re^2: Variables in Common parent class
by perlbaski (Acolyte) on Mar 14, 2013 at 06:51 UTC
    I tried your program after moving the package code to different files, error from MyModule says undefined subroutine at SuperModule::new. Works only if SuperModule and MyModule are in same file.

    How can I make it see the new from SuperModule.pm?

      Organise the code like this:

      File main.pl:

      #! perl use strict; use warnings; use MyModule; use YourModule; # ... as before ...

      File SuperModule.pm:

      #! perl package SuperModule; # ... as before ... 1;

      File MyModule.pm:

      #! perl package MyModule; use strict; use warnings; use SuperModule; our @ISA = qw( SuperModule ); # ... as before ... 1;

      File YourModule.pm:

      #! perl package YourModule; use strict; use warnings; use SuperModule; our @ISA = qw( SuperModule ); # ... as before ... 1;

      Note that a standalone module (i.e., a file with a .pm extension) must return true on success. Hence the common practice of ending each module with 1; on a line by itself. See Perl Modules in perlmod.

      This scheme assumes that the four files are in the same directory. If they’re not, you will need to investigate the use lib pragma. See lib.

      Hope that helps,

      Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://1022642]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others contemplating the Monastery: (11)
As of 2014-07-23 06:49 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My favorite superfluous repetitious redundant duplicative phrase is:









    Results (134 votes), past polls