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

For some reason I can't seem to get a sub to export into my main program. I'm probably just doing something stupid. Here's the code:
package AAIB::Login; # this is a little login routine that I'm using use strict; use Exporter; my @ISA = ('Exporter'); my @EXPORT_OK = qw(authenticate); # I've also tried @EXPORT = qw(authenticate); # etc ...(returns a hash)

And then my main program:
use strict; # use a bunch of other modules use AAIB::Login qw(authenticate); my %usr = authenticate();

Then at that point the program crashes saying "Undefined subroutine &main::authenticate;. Its very frustrating I have a similar program that does basically the same thing and it imports the subs just fine. Can anyone spot the error?

Thanks in advance,
Chris

Replies are listed 'Best First'.
Re: Problems Exporting subs
by danger (Priest) on Dec 03, 2001 at 22:21 UTC

    The @ISA and @EXPORT_OK arrays need to be package variables, not lexicals. Change the my()'s to our()'s, or 'use vars ...', or simply place 'strict' after initialization of the special arrays and don't declare them at all.

    this: package Blah; use strict; require Exporter; our @ISA = qw/Exporter/; our @EXPORT_OK = qw/authenticate/; # ... or, package Blah; require Exporter; @ISA = qw/Exporter/; @EXPORT_OK = qw/authenticate/; use strict; # ... or, package Blah; use strict; use vars qw/@ISA @EXPORT_OK/; require Exporter; @ISA = qw/Exporter/; @EXPORT_OK = qw/authenticate/; # ...

      Can you explain the difference between the three apporaches?

      -- Ian Stuart
      A man depriving some poor village, somewhere, of a first-class idiot.

        The main difference between the three approaches is merely syntax :-)

        Ok, first the requirement is that the various special module variables such as:  @ISA, @EXPORT_OK, $VERSION have to be package variables (not lexicals). One way to have package variables without having strict complain is simply to not turn on strict until you are done referring to such variables (that is, initializing or otherwise explicitly using the variables). Any time you use a variable (that hasn't been declared) is is automatically a package variable belonging to the current package. In general this isn't a great way to deal with global/package variables --- but, in the case of these special module variables, you usually only use them once (initialization) and that's it, so it seems acceptable in my mind to defer turning on strict until after these variables are initialized.

        Another way to handle global/package variables and strict is to declare such variables with the 'use vars' pragma --- this essentially tells strict that these variables are OK to use without full package qualification. This is perhaps the best alternative of the three (see below for why).

        Finally, with 5.6+ there is the new declaration our(). This does what 'use vars' does except that it is a lexically scoped declaration --- ie, you can refer to such variables without package qualification for the duration of the current lexical scope (in this case the whole file). I generally don't find our very useful, and it also means your module is restricted to being used with versions of Perl at 5.6 or higher. On the other hand, you don't have to type the variable twice (with vars you need to declare it, then you can initialize it, with our you can do both in one statement). The h2xs utility (which eases building module packages) now uses our as the method of choice.

        All this talk of package variable qualification brings up a fourth alternative --- simply using fully qualified package names for the variables.

        package Blah; use strict; require Exporter; @Blah::ISA = qw/Exporter/; @Blah::EXPORT_OK = qw/whatever/; #...

        Using fully qualified names instead of declaring them with vars or our is not recommended for two reasons: 1) you lose any typo-checking that strict gives if you use the variable in more than one place, and 2) who wants to type that much? --- and 3) it looks kind of ugly, no?

        Which one should I use? Well, TMTOWDI, but I would recommend using the vars approach for the following reasons: a) works with earlier versions of Perl; b) you still get strict's typo checking (assuming you spelled them correctly the first time), and c) if you need other package variables (for exporting or whatever), you declare them right along with the special module variables:

        package Blah; use strict; use vars qw/@ISA @EXPORT_OK $VERSION $Something_else/; #...

        I hope that clarifies rather than confuses the issue.

Re: Problems Exporting subs
by Fletch (Bishop) on Dec 03, 2001 at 22:22 UTC

    Exporter is going to want @EXPORT_OK to be a package variable, not a lexical. @ISA also needs to be a package variable as well. Remove the my from the declaration (you can declare them either using our, fully qualifying the name (@AAID::Login::ISA), or use vars qw( @ISA );).

Re: Problems Exporting subs
by chip (Curate) on Dec 03, 2001 at 23:53 UTC
    This error isn't very common, but it occurs to me that the Perl compiler should warn when my is applied to a variable name that really should be global, like @EXPORT_OK and @ISA.

        -- Chip Salzenberg, Free-Floating Agent of Chaos

Re: Problems Exporting subs
by Anonymous Monk on Dec 04, 2001 at 00:42 UTC
    Try putting your routine in a foo.pl file and just performing a require "foo.pl"; in your main program. That is the usual way I export subs() since I could not get the Exporter to work.
Re: Problems Exporting subs
by cfreak (Chaplain) on Dec 04, 2001 at 00:44 UTC
    I have fixed it now. Thanks to all for the comments. Sort of a 'duh' thing :)