Seitenanfang

use Problems; with Exporter and import

Dieser Post wurde aus meiner alten WordPress-Installation importiert. Sollte es Darstellungsprobleme, falsche Links oder fehlende Bilder geben, bitte einfach hier einen Kommentar hinterlassen. Danke.


The Exporter-module "copies" functions and symbols from a module into other files - but not reliable.

It's documentation says:

  package YourModule;  require Exporter;  @ISA = qw(Exporter);  @EXPORT_OK = qw(munge frobnicate);  # symbols to export on request

or

package YourModule; use Exporter 'import'; # gives you Exporter's import() method directly @EXPORT_OK = qw(munge frobnicate); # symbols to export on request

But both suggestions fail if the exporting module loads other modules via "use" which "use" the exporting module itself. No error message is generated, but nothing is exported either and errors occur somewhere within the running program when the (not) exported/imported functions are called. "use base 'Exporter';" and indirect loads (A uses B, B uses C, C uses A) make no difference.

The problem is based on the processing of modules during Perl's compilation phase:

A.pm: use B;B.pm: use A;
The "use A;" within the B.pm isn't executed. A.pm has been "loaded" first and is on the "use"-stack when B.pm's "use A;" is compiled. Compiling "A.pm" again would result in a compilation loop so Perl skips it.The import()-function for A.pm is called for the "use A;" in B.pm, but A's @EXPORT* variables haven't been filled yet - nothing is imported. The @EXPORT* variables are defined in "normal" source which is executed after everything is compiled. (Another posts describes use, BEGIN and other problems more detailed.)

Two basic rules solve this problem:

1. Early use Exporter

The Exporter module should be loaded as soon as possible but always before and other module which might call back the exporting one. If Exporter is "use base"ed first, import() is available early enough for being found by subsequent use'es from other modules.

2. BEGIN defining Exporter configuration

The Exporter configuration should be defined in an early BEGIN block.
package A.pm;

use base 'Exporter';

BEGIN {our @EXPORT = qw(foo);}

use B;

BEGIN-Blocks are executed in order of appearance within the compilation phase of the file, just like the "use" commands. Exporter is loaded as the first module and the Exporter configuration is defined next. Any implicit import() call within B.pm or GLOBAL::Something may use the exported symbols and succeed.
 

Noch keine Kommentare. Schreib was dazu

Schreib was dazu

Die folgenden HTML-Tags sind erlaubt:<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>