Search code examples
perlparent-childsubroutine

Perl: Best way of making parent subroutine (not method) available to children


I have multiple classes defined in my main program. One is a parent class. The other are children classes:

# Main Program
...

package Foo;           #Parent class
....

sub glob2regex {
    my $glob = shift;
    ...here be dragons...
    return $regex;
};

....

package Foo::Bar;      #Child Class
base qw(Foo);

sub some_method {
   my $self = shift;
   my $regex = shift;
   my $type  = shift;

   if ( $type eq "glob" ) {
      $regex = glob2regex($regex);   #ERROR: glob2regex is not defined.
   }
   ...
}

I have a function in my parent class called glob2regex. It isn't really a method because it doesn't do anything with the object. Instead, it's a helper function that my child classes can use.

However, calling it in my child class as shown above won't work because it's not defined in my child class. I could prepend the full parent class name on it (i.e. call it as Foo::glob2regex instead of just glob2regex), or I could modify it into an object, and call it as $self->glob2regex. There maybe a even better way of handling this situation that I'm overlooking.

What is the best way to make a function like this that's defined in the parent class available in the child classes?

--

Test Program

#! /usr/bin/env perl
#
use strict;
use warnings;
use feature qw(say);
use utf8;

########################################################################
# MAIN PROGRAM 
my $bar = Foo::Bar->new;
$bar->just_foo_it;
#
########################################################################

########################################################################
#
package Foo;

sub lets_foo_it {
    say "I've done foo!";
}
#
########################################################################

########################################################################
#
package Foo::Bar;
use base qw(Foo);

*Foo::Bar::lets_foo_it = *Foo::lets_foo_it;

sub new {
    my $class = shift;
    my $self = {};
    bless $self, $class;
    return $self;
}

sub just_foo_it {
    my $self = shift;

    lets_foo_it();
}
#
########################################################################

Solution

  • Exporting is usually done using Exporter.

    BEGIN {
       package Foo;
       use Exporter qw( import );
       our @EXPORT_OK = qw( glob2regex );
       sub glob2regex { ... }
       ...
       $INC{'Foo.pm'} = 1;
    }
    
    BEGIN {
       package Foo::Bar;
       use Foo qw( glob2regex );
       our @ISA = 'Foo';
       ... glob2regex(...) ...
       $INC{'Foo/Bar.pm'} = 1;
    }
    

    Note that it's very unusual for a class module to export subroutines. You should consider it a red flag indicating a likely design flaw.