The short version is that you wanted a module, but you ended up with what this calls a library. These aren't good because they pollute their caller's namespace (which can cause plenty of problems). But more crucially here, loading them using require
or use
(as oppose to do
) is buggy.
If it had been properly written as a module, your example would not work. Exporter is the solution to that problem.
Let's dive into the details.
Like I said, there's a problem with your module. As you've noticed, it sometimes works despite the bug.
$ cat Buggy.pm
sub test { "ok!" }
1;
$ perl -e'use Buggy; CORE::say(test());'
ok!
But that's just because your example is too simple. Let's add a properly-written[1] module to the mix.
$ cat Buggy.pm
sub test { "ok!" }
1;
$ cat Other.pm
package Other;
use Buggy;
1;
$ perl -e'use Other; use Buggy; CORE::say(test());'
Undefined subroutine &main::test called at -e line 1.
The bug in your module is that it doesn't have a package
directive. Modules loaded using use
and require
must always use a package
directive. But as soon as you add that, your module stops working.
$ cat NotBuggy.pm
package NotBuggy;
sub test { "ok!" }
1;
$ perl -e'use NotBuggy; CORE::say(test());'
Undefined subroutine &main::test called at -e line 1.
Exporter is used to solve that problem.
$ cat Final.pm
package Final;
use Exporter qw( import );
our @EXPORT = qw( test );
sub test { "ok!" }
1;
$ perl -e'use Final; CORE::say(test());'
ok!
- Well, not really. If it was properly written, it would include use
use strict; use warnings 'all';
. Always include that! It was omitted here to keep things visually simple.