Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

export vs export_ok in perl

I can not understand what is the difference/use case of EXPORT_OK vs EXPORT.
Most resources mentions something in the lines of:

@Export allows to export the functions and variables of modules to user’s namespace using the standard import method. This way, we don’t need to create the objects for the modules to access its members.
@EXPORT_OK does export of symbols on demand basis for selective list of symbols (subroutines and variables) of the module.

But I really don't see the difference/meaning here.
Can someone please provide a small fundamental example of the difference/usage of these 2 symbols?

like image 348
Jim Avatar asked Jul 28 '13 20:07

Jim


People also ask

What is export in Perl?

Perl's Exporter module allows modules to "export" identifiers (i.e., variable and subroutine names) into the calling program's namespace. Once exported, an identifier has two names—one in the module's package and another in the importing program's package.

What is the difference between use and require in Perl?

The differences are many and often subtle: use is evaluated at compile-time, require at run-time. use implicitly calls the import method of the module being loaded, require does not. use excepts arguments in addition to the bareword (to be passed to import), require does not.

What is require in Perl?

Description. This function then it demands that the script requires the specified version of Perl in order to continue if EXPR is numeric. If EXPR or $_ are not numeric, it assumes that the name is the name of a library file to be included.


2 Answers

Let's say I have a package MyPackage that uses @EXPORT.

#this is MyPackage.pm
package MyPackage;
@EXPORT = qw(do_awesome_thing);

sub do_awesome_thing { ... }

sub be_awesome { ... }

Now, when I use MyPackage in my code,

#this is myscript.pl
use MyPackage;

do_awesome_thing(); #works

be_awesome(); #doesn't work
MyPackage::be_awesome(); #works

do_awesome_thing gets automatically exported to my code from MyPackage, without me having to say "give this to me". be_awesome isn't exported (and it won't be exported with @EXPORT_OK either, I'm just showing that part to get you clear on what "exporting" gives us).

On the other hand, if I have a package MyOtherPackage that uses @EXPORT_OK,

#this is MyOtherPackage.pm
package MyOtherPackage;
@EXPORT_OK = qw(do_awesome_thing);

sub do_awesome_thing { ... }

sub be_awesome { ... }

and then try

#this is mynewscript.pl
use MyOtherPackage;

do_awesome_thing(); #doesn't work
MyOtherPackage::do_awesome_thing(); #works, as always

the line calling do_awesome_thing directly won't work. This is because putting something in @EXPORT_OK says "give this to my users only if they ask for it". Since we've just said use MyOtherPackage without explicitly asking for do_awesome_thing to be imported here, it doesn't get imported, and is accessible only by specifying the package name.

The way you ask for do_awesome_thing to be imported is to say use MyOtherPackage qw(do_awesome_thing) in the second line of mynewscript.pl above. This says import that module and make do_awesome_thing available directly. After that, the fourth line in mynewscript.pl above will start working.

Note that the user can specify use MyPackage qw(do_awesome_thing) with the first package also, and in that case, anything else in the @EXPORT list won't be exported, only do_awesome_thing will be. So, except for the default case of use PackageName;, @EXPORT and @EXPORT_OK behave similarly. In the default case, anything in @EXPORT gets thrown into the user's script automatically, while @EXPORT_OK is more polite and doesn't export anything.

like image 197
Sundar R Avatar answered Oct 07 '22 18:10

Sundar R


From the fine Exporter manual:

  • use YourModule;
    This imports all the symbols from YourModule's @EXPORT into the namespace of the use statement.
  • use YourModule ();
    This causes perl to load your module but does not import any symbols.
  • use YourModule qw(...);
    This imports only the symbols listed by the caller into their namespace. All listed symbols must be in your @EXPORT or @EXPORT_OK, else an error occurs. The advanced export features of Exporter are accessed like this, but with list entries that are syntactically distinct from symbol names.

So, if you use @EXPORT and someone does the usual use YourModule;, then you've just polluted their namespace with everything in @EXPORT. But, if you use @EXPORT_OK, they have to specifically ask for things to be imported so the person using your module has control over what happens to their namespace.

The difference is really a matter of who controls what gets into the user's namespace: if you use @EXPORT then the module being used does, if you use @EXPORT_OK then the code doing the import controls their own namespace.

Of course, you could always say use Whatever(); to keep impolite modules from polluting your namespace but that's ugly and you shouldn't have to kludge around rude code that wants to scribble all over your namespace.

like image 42
mu is too short Avatar answered Oct 07 '22 18:10

mu is too short