Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do Perl subclasses inherit imported modules and pragmas?

Tags:

perl

Lets say you have a parent Perl class in one file:

#!/usr/bin/perl
package Foo;
use strict;
use warnings;

use Data::Dumper;

sub new{
    my $class = shift;
    my %self = ();
    return bless %self, $class;
}
1;

and a subclass in a different file:

#!/usr/bin/perl
package Bar;
use base "Foo";
1;

Will the subclass inherit the use statements from the parent? I know the method new will be inherited.

Basically I am trying to reduce the amount of boilerplate in my code and I can't find a clear answer to this question.

like image 609
chotchki Avatar asked Aug 11 '10 16:08

chotchki


1 Answers

You asked in a comment about Test::Most and how it reduces boilerplate. Look at its import method. It's loading the modules into its namespace, adding those symbols to @EXPORT, then re-calling another import through a goto to finally get them into the calling namespace. It's some serious black magic that Curtis has going on there, although I wonder why he just didn't use something like import_to_level. Maybe there are some side effects I'm not thinking about.


I talk quite a bit about this sort of thing in Avoid accidently creating methods from module exports in The Effective Perler. It's in a different context but it's some of the same issues.

Here's a different example.

If some other module loads a module, you have access to it. It's not good to depend on that though. Here are three separate files:

Top.pm

use 5.010;

package Top;
use File::Spec;

sub announce { say "Hello from top!" }
1;

Bottom.pm

package Bottom;
use parent qw(Top);

sub catfiles { File::Spec->catfile( @_ ) }

1;

test.pl

use 5.010;

use Bottom;

say Bottom->catfiles( qw(foo bar baz) );

say File::Spec->catfile( qw( one two three ) );

I only load File::Spec in Top.pm. However, once loaded, I can use it anywhere in my Perl program. The output shows that I was able to "use" the module in other files even though I only loaded it in one:

Bottom/foo/bar/baz
one/two/three

For this to work, the part of the code that loads the module has to load before any other part of the code tries to use that module. As I said, it's a bad idea to depend on this: things break if the loading sequence changes or the loading module disappears.

If you want to import symbols, however, you have to explicitly load the module you want while you are in the package you want to import into. That's just so the exporting module defines the symbols in that package. It's not something that depends with scope.

like image 84
brian d foy Avatar answered Oct 01 '22 07:10

brian d foy