Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Perl, why do I need Exporter?

I have a module called hsfSubs.pm in my perl\lib folder. I have nothing in the module but subroutines and 1; at the end.

One subroutine, for example, is named pause. I have implemented no import or export routines.

In my main programs, I simply say use hsfSubs;, and I am subsequently able to call pause with no problem. Ditto if I say use hsfSubs qw(pause);.

Why would I need to use Exporter, @EXPORT and @EXPORT_OK, etc. or any other complications?

The multiple answers on Stack Overflow to questions about Exporter tell how to use it, but I fail to see why to use it.

like image 862
user1067305 Avatar asked Jul 05 '16 02:07

user1067305


1 Answers

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!

  1. 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.
like image 174
ikegami Avatar answered Sep 21 '22 13:09

ikegami