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

I have two modules, say they are /opt/lib/A.pm and /opt/lib/B.pm.
A script can use them by:
use lib '/opt/lib'; use A; use B;
But, my module B want to access the methods in module A. what's the right way for this purpose?
maybe making an inheritance relationship for B to A?

Thanks.

Replies are listed 'Best First'.
Re: modules relation question
by tobyink (Canon) on Jun 16, 2023 at 06:09 UTC

    Without more information it's hard to say what is the best way to achieve this. Using names more specific than "A" and "B" might give us more clues about what you need.

    Inheritance is for object-oriented programming, where one class is logically a subclass of another class. For example, if you have "Animal" and "Bear" packages, it would make sense for "Bear" to inherit from "Animal".

    # lib/Animal.pm package Animal; sub new { my $class = shift; return bless {}, $class; } sub is_furry { my $self = shift; warn "We don't know if this animal is furry or not!\n"; return undef; } sub make_noise { my ( $self, $noise ) = @_; print $noise, "\n"; } 1; # lib/Bear.pm package Bear; use base 'Animal'; # We know bears are furry, so override Animal's is_furry method: sub is_furry { my $self = shift; return 1; } sub eat_honey { my $self = shift; # Make use of Animal's make_noise method: $self->make_noise( "Yum!" ); } 1; # example.pl use Animal; use Bear; my $baloo = Bear->new; if ( $baloo->is_furry ) { $baloo->eat_honey; }

    If you're not using object-oriented programming, then you don't want inheritance. For example, if your modules are "AliceUtils" and "BobUtils" and Bob wants to use a few of Alice's utility functions in his code, then:

    # AliceUtils.pm package AliceUtils; sub safe_filename { my $string = shift; $string =~ s{\W}{}g; $string = "untitled" if !$string; return $string; } 1; # BobUtils.pm package BobUtils; use AliceUtils; # Make sure it's loaded! sub save_data { my ( $filename, $data ) = @_; my $safe_filename = AliceUtils::safe_filename( $filename ) . ".txt"; open my $fh, '>', $safe_filename or die; print $fh $data or die; close $fh or die; return $safe_filename; } 1; # example.pl use AliceUtils; use BobUtils; BobUtils::save_data( "my file", "Hello world!\n" );

    Often you don't want to fully-qualify sub names like BobUtils::save_file and would prefer to call them by just their unqualified sub name like save_file. If you want that, then you make the modules exporters. For this example, I'm going to use Exporter::Shiny to do that, because it's simple and I made it. There are many other ways to turn your module into an exporter though, including Exporter.pm which comes bundled with Perl.

    # AliceUtils.pm package AliceUtils; # Tell Exporter::Shiny which functions to make available to others: use Exporter::Shiny 'safe_filename'; sub safe_filename { my $string = shift; $string =~ s{\W}{}g; $string = "untitled" if !$string; return $string; } 1; # BobUtils.pm package BobUtils; # Tell AliceUtils which functions we want from it: use AliceUtils 'safe_filename'; # Tell Exporter::Shiny which functions to make available to others: use Exporter::Shiny 'save_data'; sub save_data { my ( $filename, $data ) = @_; my $safe_filename = safe_filename( $filename ) . ".txt"; open my $fh, '>', $safe_filename or die; print $fh $data or die; close $fh or die; return $safe_filename; } 1; # example.pl use AliceUtils; use BobUtils 'save_data'; save_data( "my file", "Hello world!\n" );

    (Generally speaking, if your module is written to be used as a class in object-oriented programming, it should not be an Exporter. Exporters are more for bundles of utility functions. And yes, I know there are exceptions to this rule.)

Re: modules relation question
by kcott (Archbishop) on Jun 16, 2023 at 06:07 UTC

    G'day wsly,

    Welcome to the Monastery.

    [That's an unfortunate choice of example module names as B already exists and is a core module. I'm going to pretend you wrote X and Y. You may want to change that in your post; How do I change/delete my post? explains how to do this.]

    There's a number of ways to do this. Please tell us about the relationship between these two modules. Here's some possibilities:

    • X exports functions; Y imports them.
    • Y is a subclass of X: an inheritance relationship.
    • X is a component of Y: a composition relationship.
    • X is an optional feature of Y: an aggregation relationship.

    You may want to look at Exporter for the first of those relationships; or "perlootut - Object-Oriented Programming in Perl Tutorial" for the remainder.

    — Ken