How to call a method in a base class in Perl

# child.pm

#!/usr/bin/perl package child1; use strict; use warnings; use Exporter; use parent; my @ISA=qw(cal Exporter); sub new{ my $class=shift; my $ref=cal->new(); bless ($ref,$class); return $ref; } sub add{ my $ref=shift; print "This is from child class"; my($a,$b) =@ _; return ($a+$b); } 

# # parent.pm

 #!/usr/bin/perl package cal; use strict; use warnings; use Exporter; my @EXPORT=qw(add); my @ISA=qw(Exporter EXPORT); sub new{ my $class=shift; my $ref=[]; bless ($ref,$class); return $ref; } sub add{ my $ref=shift; my $a=shift; my $b=shift; return ($a+$b); } 1; 

# test.pl

 #!/usr/bin/perl use strict; use warnings; use Exporter; use child; my @ISA=qw(child1 Exporter); my $obj=new child1(); my $sum=$obj->add(1,2); print "$sum=sum"; 

I get an error. Cannot find the method of the object "add" through the package "child1" to the string. /test.pl 8. I want to access the method of adding a base class and I get this error above

please clarify ..

+6
source share
3 answers

The .pm modules are not needed and probably do not want the lines #! / Usr / bin / perl. This is only for programs designed to be executed from the command line, for example, your .pl module. While you can "perl -cw" your .pm modules or debug another command line with them, this is not the usual "production".

And .pl modules should not have @ISA or other "our" ads found in packages, and any things related to the exporter.

As already mentioned, change β€œmine” to β€œours” on the package material. β€œMy” hides things to strangers, as if there had never been a statement.

In the cal class, do you want something like the following? I prefer SUPER, as it really shows what is going on and is much more general .

  package child1;
 use exporter;
 our @ ISA = qw (cal Exporter);

 sub new {
         my $ class = shift;
         my $ ref = $ class-> SUPER :: new () ;
         return $ ref;
         }
 } 

One last point: you may need "\ n" in the last print statement. Without it, the buffer may not merge correctly when exiting in some environments, so you will never see the result.

+6
source

The main culprit here is my @ISA . For inheritance to work, you need to use the @ISA package (declare it using our ).

However, there are some problems in your code:

  • Please use parent 'cal' instead of manipulating @ISA yourself.
  • Object-oriented modules have little reason to use Exporter .
  • Child1 new can be written without restarting because the parent new inherited. Inherited new written in a way that already supports inheritance.
  • Do not specify the names of your modules in lower case, they are reserved for pragmas. The parent module already exists, and I used it at my first point.
+10
source

@ISA should be a public package variable, not private vocabulary ( my ). Same thing for @EXPORT . Change my to our for all of these declarations.

Even better, depending on the version of perl you have, make life easier with parent or base pragma to load superclasses and to establish class relationships.

Regarding style, you will avoid significant confusion if you create paths to files that contain your module code that match their package names. You would well consider the well-established convention described in the perlmod documentation.

Module names are also capitalized if they do not function as pragmas; pragmas are valid compiler directives and are sometimes called "pragmatic modules" (or even "pragmatics" if you are a classic).

The Cal module uses the _initialize internal method, as described in the perlobj documentation , to facilitate constructor inheritance.

See below for a complete working example.

Cal.pm

 package Cal; use strict; use warnings; sub new { my $class=shift; my $self=[]; bless ($self,$class); $self->_initialize(); return $self; } sub _initialize {} sub add { my $ref=shift; my $a=shift; my $b=shift; print "This is from parent class\n"; return ($a+$b); } 1; 

Child1.pm

 package Child1; use warnings; use strict; use v5.10.1; # when parent was added to the core use parent "Cal"; # if you have an older perl, use base instead of parent # use base "Cal"; sub _initialize { my $self=shift; push @$self, "I am a " . ref($self) . "!"; } sub add{ my $self=shift; my($a,$b) =@ _; print "This is from child class\n"; return ($a+$b); } 1; 

test.pl

 #!/usr/bin/perl use strict; use warnings; use Child1; my $obj=Child1->new(); my $sum1=$obj->add(1,2); print "$sum1=sum1\n"; # call the add method in Cal my $sum2=$obj->Cal::add(1,2); print "$sum2=sum2\n"; # call add as a class method of Cal, which # happens to work in this case because Cal::add # does not use the instance passed to it my $sum3=Cal->add(1,2); print "$sum3=sum3\n"; 

Output:

  This is from child class
 3 = sum1
 This is from parent class
 3 = sum2
 This is from parent class
 3 = sum3 
+4
source

Source: https://habr.com/ru/post/950180/


All Articles