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

This is kind of a follow up to this question, which i posted earlier I have been running into this not so uncommon error:

Undefined subroutine &csDB::csErrorClass called at f:/projects/site/bin/lib//csDB.pm line 55

which is a no brainer because of course csErrorClass is in my csLogs::Error.pm module, which I then 'use' in csDB.pm.

perl -w -McsDB -e 1; runs without a hitch, so the problem seems to be when the csDB module is used from other scripts which also use the Error.pm module.

From the last thread (linked above) it sounds like the Exporter module's import routine simply aliases the EXPORT'ed variables/subs etc into the current namespace, but does it do this each time the module is included? If I have 3 module files and a script all of which reference a 4th module file, will all of the normally exported symbols from that module be exported into all four of the other namespaces, or just whichever of them gets to say "use Module4" first?

The application behind this question is a core module that redirects some of perl's error handling to a form more useful for me (both by setting SIG handlers for warn and die, and by providing some replacements for warn and die as used in "or die" statements by programmers). As such, i need to have access to the functions in this module from just about every other file in my set of scripts & modules.

Replies are listed 'Best First'.
Re: exporter and multiple namespaces
by btrott (Parson) on May 01, 2001 at 23:11 UTC
    Yes, import should run each time the module gets 'use'-d by a script/module/program/etc. 'use' is essentially a BEGIN block that first requires the other module, then runs its import class method. The file won't get re-loaded (ie. required) each time you use it, but the import method will get called each time.

    You can test this by writing in your own import method and putting some debugging statements inside of it, eg. using caller to see who's calling import.

    But, in a sort of unrelated to your question thing, you say that you're going to be using these functions in almost every one of your scripts and modules. In that case, might I suggest thinking about an OO approach? It may not fit your model, in which case go with the exported functions; but if it does fit, you'll be saving on a lot of exported symbol table entries, if you're really going to export functions to each of your namespaces. Just a thought, anyway; I'm not saying "go OO", just to think about it if you haven't already.

      I am quite happy to use OO much of the time, however at this point I was trying to be minimally syntactically invasive. By this i mean I'd like to be able for other developers using my library to be able to go from this:

      open(FILE,"foo.txt") or die "couldn't open file";

      to this:

      use csLogs::Error; open(FILE,"foo.txt") or csDie(...);

      The use of the error module is supposed to be as far away from the spotlight as possible, so I am looking to keep things as transparent to the programmers as possible

        That sounds fine; particularly after seeing your intended interface I withdraw all thoughts about using an OO approach. :) One shouldn't have to instantiate an object just to die.

        Anyway, though, would you mind posting some of your code? Is it possible that you have your functions in @EXPORT_OK and that you're not importing them explicitly? Just an idea.

Re: exporter and multiple namespaces
by Anonymous Monk on May 02, 2001 at 01:11 UTC
    Maybe I'm way off here... but when I get that error message, it's usually because I've typed
    $err = csDB::csErrorClass();
    instead of
    $err = csDB::csErrorClass->new();
      no, the csErrorClass module is in a module that's use'd by csDB, and it isn't an OO module at that. You'll notice further down the first thread on this post I mention that the Name of the sub is being exported successfully, but that apparently isn't a guarantee.