Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get reference to parent class subroutine perl

I have a situation where in child class, I need a reference of subroutines defined in parent class which I need to pass to some other class which would execute them. So I was wrote following sample modules for testing the same.

Parent1.pm

package Parent1;

sub new {
    my ($class, $arg_hash) = @_;

    my $self = bless $arg_hash, $class; 

    return $self;
}

sub printHello{

    print "Hello\n";
}

sub printNasty{
    print "Nasty\n";
}
1;            

Child1.pm

package Child1; 

use base Parent1;

sub new {
    my ($class, $arg_hash) = @_;

    my $self = bless $arg_hash, $class; 

    return $self;
}

sub testFunctionReferences{

    my ($self) = @_;

    # Case 1: Below 2 lines of code doesn't work and produces error message "Not a CODE reference at Child1.pm line 18."
    #my $parent_hello_reference = \&$self->SUPER::printHello;
    #&$parent_hello_reference();

    # Case 2: Out of below 2 lines of code, 1st line executes the function and produces output of "Hello\n" but 2nd line doesn't work and produces error message "Not a CODE reference at Child1.pm line 23."
    #my $parent_hello_reference2 = \$self->SUPER::printHello;
    #&$parent_hello_reference2();

    # Case 3: does not work either. Says "Undefined subroutine &Child1::printNasty called at Child1.pm line 27"
    #my $parent_nasty_reference = \&printNasty;
    #&$parent_nasty_reference();

    # Case 4: works. prints "World\n" as expected  
    #my $my_own_function_reference = \&printWorld;
    #&$my_own_function_reference();

    # Case 5: works. prints "Hello\n" and  "Nasty\n" as expected
    #$self->printHello();
    #$self->SUPER::printNasty();

    # Case 6: does not work produces error "Undefined subroutine &Child1::printHello called at Child1.pm line 38" 
    #printHello();
    return;
}

sub printWorld{
    print "World\n";
}   

test.pl

#!/usr/bin/perl

use Child1;

my $child = Child1->new({});

$child->testFunctionReferences();

So my questions are:

  1. As in case 1, what is the correct syntax to get a reference to parent subroutine?

  2. When I use inheritance, how can I call the parent function directly as in case 6? Is it even possible in perl?

  3. When case 5 works then why not case 6?

Any insights are appreciated. Thanks

like image 711
chammu Avatar asked Sep 29 '22 10:09

chammu


1 Answers

If printHello is a subroutine, use

my $sub = \&Parent::printHello;

If printHello is a method, use

# This line must appear inside of the Child package.
my $sub = sub { $self->SUPER::method(@_) };

If you want a code reference, you need a subroutine to reference, and this creates one.


In both cases, you can call the sub using

&$sub();

or

$sub->();

(I find the latter cleaner, but they are otherwise equivalent.)

like image 121
ikegami Avatar answered Oct 05 '22 06:10

ikegami