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

I originally learned what Perl I know back in the 90's, and tended then (and still do, sometimes) to put common subroutines into a 'standard.pl' library which I would 'require' where needed. I know that most people bundle such routines into a module these days, and I understand some of the reasons for this. I was burned today and wondered if someone could explain to me (using small words) just why.

Suppose I have the following modules:

package A; use B; require 'standard.pl'; sub new { # [snip] bless ($self, $class); do_something(); # subroutine in standard.pl return $self; }
package B; require 'standard.pl'; sub new { # [snip] bless ($self, $class); do_something(); # subroutine in standard.pl return $self; }
# standard.pl # [snip] sub do_something { print "Howdy.\n"; } 1;

When I tried to run a script that used module A, I got an error message like this:

Undefined subroutine A::do_something called at A.pm line X.

I eventually realized that module B was requiring the same standard.pl library and changed the code in A to no longer require the standard.pl libary and the invocation of the do_something() routine from:

do_something();

to:

B::do_something();

... which worked. It made me feel a little deceptive, referring to a common subroutine in standard.pl as though it was part of module B, though. Why couldn't module A 'see' that do_something() subroutine in its own namespace, since I explicitly 'require'-d it in both modules?

Maybe the moral of the story is that I shouldn't be mixing packages and libraries, but I would like to understand this better in any case.

Replies are listed 'Best First'.
Re: Burned by 'require'?
by phaylon (Curate) on Dec 28, 2005 at 23:37 UTC
    Namespaces are a great gift, and I'd recommend to using them :) Why don't you just place your standard library in an includable module (I usually name them MyProject::Utils or such) and use Exporter's functionality to import the wanted subroutines into the requesting namespace?(1)

    Like choedebeck pointed out, require will load the file only once. You might want to use 'do' for a quick solution, tho I'd recommend the Exporter version.

    1. (untested, see perldoc Exporter for more)
    package MyProject::Utils; use warnings; use strict; use base qw/ Exporter /; use vars qw/ @EXPORT_OK /; @EXPORT_OK = qw/ mysub_foo mysub_bar /; sub mysub_foo { ... } sub mysub_bar { ... } ... use MyProject::Utils qw/ mysub_bar /; my $x = mysub_bar( 23 );

    Ordinary morality is for ordinary people. -- Aleister Crowley
Re: Burned by 'require'?
by choedebeck (Beadle) on Dec 28, 2005 at 23:07 UTC
    Looking at the documentation on require it seems to demand a library be included if it has not already been included. Since the library was included once in package B it will not be included again in package A.

    You should be able to change the require to use and get the desired behavior.
Re: Burned by 'require'?
by Errto (Vicar) on Dec 29, 2005 at 04:39 UTC

    All subroutines are in a package. Because the required file does not declare its own package, the subroutines in that file will end up in whatever package require was called from. In this case package B. But the way require works, a given file only ever gets required once, unless you explicitly remove its name from the %INC hash. This means that you can't call that subroutine directly from A.

    In your specific situation one way to get around the problem is to make B export that subroutine as follows:

    package B; require Exporter; our @ISA = 'Exporter'; our @EXPORT = qw(do_something);
    or something like that. Either way, that require standard.pl won't do anything when you call it from package A because it's already been required from package B.