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/;
# ...
| [reply] [d/l] [select] |
| [reply] |
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.
| [reply] [d/l] [select] |
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 );).
| [reply] [d/l] [select] |
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 | [reply] [d/l] [select] |
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. | [reply] |
I have fixed it now. Thanks to all for the comments. Sort of a 'duh' thing :) | [reply] |