Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is the order of use of perl modules followed when evaluating subroutines?

Tags:

module

perl

I have a perl module that has a frequently used subroutine. For a specific set of scripts I need to override this subroutine so i created another module that has the new implementation. Does anyone know if the call order of the perl modules are always followed?

Ex.:

one.pm:

 sub temp{   print “hi”; }

two.pm:

sub temp{   print “hello”; }

sample.pl:

use one; use two;

temp();

I have tested this and it prints “hello” as expected. But I wanted to make sure that this is always the case. Is the evaluation of imported modules in order all the time?

like image 406
kdbl11 Avatar asked Jan 01 '23 10:01

kdbl11


1 Answers

You should not write modules like that! Your just going to get into problems, including the one you're asking about. Any file loaded using use should have corresponding package. And they must end on a true value. (Your code doesn't compile because you failed to do so.)

Before I got on, let me mention that you should ALWAYS use use strict; use warnings;. Also note that lowercase module names are traditionally used for pragmas, modules that change how Perl itself behaves. It's a poor practice to use lowercase module names for other purposes.

Back to the point. At a minimum, you need the following:

One.pm:

package One;
use strict;
use warnings;
sub temp { ... }
1;

Two.pm:

package Two;
use strict;
use warnings;
sub temp { ... }
1;

The script would now look like this:

use strict;
use warnings;
use One qw( );
use Two qw( );
One::temp();
Two::temp();

And now you see that your problem is moot; there's no question about which sub is called.


But, what if you didn't want to prefix all the calls with One:: or Two::? We can do that!

One.pm:

package One;
use strict;
use warnings;
use Exporter qw( import );
our @EXPORT_OK = qw( temp );
sub temp { ... }
1;

Two.pm:

package Two;
use strict;
use warnings;
use Exporter qw( import );
our @EXPORT_OK = qw( temp );
sub temp { ... }
1;

The script would now look like this:

use strict;
use warnings;
use One qw( );
use Two qw( temp );
One::temp();
Two::temp();
temp();         # Calls Two::temp() because we imported temp from Two.

If you somehow did the following or equivalent, the last one would win out.

use One qw( temp );
use Two qw( temp );

That's why it's good to always list the subs you import. Don't use

use Foo;         # Import default exports

Instead, use

use Foo qw( );   # Only import the listed exports. (None, in this case.)

If nothing else, it also makes it a lot easier to find subs and their documentation when maintaining the module.

like image 99
ikegami Avatar answered Jan 05 '23 16:01

ikegami