"use strict" in a module

"use strict" in a module

am 29.08.2007 00:09:05 von Larry

The following code:

package FooPkg;

use strict;
use Exporter ();
use vars qw/@ISA @EXPORT/;
@ISA = qw/Exporter/;
@EXPORT = qw/$x $y $z/;
use vars @EXPORT;

$x = 5;

produces:

Global symbol "$x" requires explicit package name at FooPkg.pm
line 10.
FooPkg.pm had compilation errors.

However, if I change:

use vars @EXPORT;

to

use vars qw/$x $y $z/;

it works. But I would like to avoid repeating the qw/$x $y $z/ . Why
won't the original version work?

Re: "use strict" in a module

am 29.08.2007 00:29:49 von paduille.4061.mumia.w+nospam

On 08/28/2007 05:09 PM, Larry wrote:
> The following code:
>
> package FooPkg;
>
> use strict;
> use Exporter ();
> use vars qw/@ISA @EXPORT/;
> @ISA = qw/Exporter/;
> @EXPORT = qw/$x $y $z/;
> use vars @EXPORT;
>
> $x = 5;
>
> produces:
>
> Global symbol "$x" requires explicit package name at FooPkg.pm
> line 10.
> FooPkg.pm had compilation errors.
>
> However, if I change:
>
> use vars @EXPORT;
>
> to
>
> use vars qw/$x $y $z/;
>
> it works. But I would like to avoid repeating the qw/$x $y $z/ . Why
> won't the original version work?
>

"Use vars ..." is done at compile time, so @EXPORT is unset when the
command is evaluated. For this to work, you must make sure that @EXPORT
is set at compile time too:

package FooPkg;

use strict;
use Exporter ();
use vars qw/@ISA @EXPORT/;
BEGIN {
@ISA = qw/Exporter/;
@EXPORT = qw/$x $y $z/;
}
use vars @EXPORT;

__HTH__

http://perldoc.perl.org/perlsub.html

Re: "use strict" in a module

am 29.08.2007 22:29:04 von Ferry Bolhar

Larry:

> use strict;
> use Exporter ();
> use vars qw/@ISA @EXPORT/;
> @ISA = qw/Exporter/;
> @EXPORT = qw/$x $y $z/;
> use vars @EXPORT;
>
> $x = 5;
>
> produces:
>
> Global symbol "$x" requires explicit package name at FooPkg.pm
> line 10.
> FooPkg.pm had compilation errors.
>
> However, if I change:
>
> use vars @EXPORT;
>
> to
>
> use vars qw/$x $y $z/;
>
> it works. But I would like to avoid repeating the qw/$x $y $z/ . Why
> won't the original version work?

Because "use" is a _compiler_ directive, processed much earlier that the
assignment to @EXPORT which gets executed at _run-time_. When
the

use vars @EXPORT;

is processed (and the resultant module code gets executed), @EXPORT
doesn't yet contain any variable names, so the "use vars" has nothing to do
(similar to a "use vars;").

One could write

BEGIN {
@EXPORT = qw/$x $y $z/;
}
use vars @EXPORT;

and it should work as expected, but I'd avoid code techniques like this,
because it makes your code harder to read.

Greetings, Ferry
--

Re: "use strict" in a module

am 30.08.2007 00:29:13 von Ben Morrow

Quoth Larry :
> The following code:
>
> package FooPkg;
>
> use strict;
> use Exporter ();
> use vars qw/@ISA @EXPORT/;
> @ISA = qw/Exporter/;
> @EXPORT = qw/$x $y $z/;
> use vars @EXPORT;
>
> $x = 5;
>
> produces:
>
> Global symbol "$x" requires explicit package name at FooPkg.pm
> line 10.
> FooPkg.pm had compilation errors.
>
> However, if I change:
>
> use vars @EXPORT;
>
> to
>
> use vars qw/$x $y $z/;
>
> it works. But I would like to avoid repeating the qw/$x $y $z/ . Why
> won't the original version work?

As has been explained, you would need to assign to @EXPORT at compile
time. There is a pragma on CPAN, vars::i, which will do this for you, so
you could say

use vars::i '@EXPORT' => qw/$x $y $z/;
use vars @EXPORT;

but in any case 'use vars' is considered bad style nowadays (since perl
5.6). The currently recommended way to write the above would be

use strict;

use Exporter ();
our @ISA = qw/Exporter/;

our ($x, $y, $z);
our @EXPORT = qw/$x, $y, $z/;

which still leaves you repeating the list of variables... consider it a
'tax' on exporting things. You should not export (especially variables)
without good reason :).

(Note that in the presence of subsequent 'package' statements, the
behaviour of 'our' is not quite the same as that of 'use vars'. For
instance, given

package A;
our $foo;

package B;
print $foo;

$foo refers to $A::foo, not $B::foo.)

Ben