"use strict" in a module

Discussion in 'Perl Misc' started by Larry, Aug 28, 2007.

  1. Larry

    Larry Guest

    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?
     
    Larry, Aug 28, 2007
    #1
    1. Advertising

  2. Larry

    Mumia W. Guest

    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
     
    Mumia W., Aug 28, 2007
    #2
    1. Advertising

  3. Larry

    Ferry Bolhar Guest

    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
    --
     
    Ferry Bolhar, Aug 29, 2007
    #3
  4. Larry

    Ben Morrow Guest

    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
     
    Ben Morrow, Aug 29, 2007
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. H. Wade Minter
    Replies:
    8
    Views:
    346
    Robin
    Apr 25, 2004
  2. Martina

    why is important to use : use strict?

    Martina, Sep 19, 2005, in forum: Perl Misc
    Replies:
    6
    Views:
    113
    J├╝rgen Exner
    Sep 20, 2005
  3. Ting Wang
    Replies:
    5
    Views:
    202
    John Bokma
    Oct 6, 2005
  4. Peng Yu

    When to use "use strict;"?

    Peng Yu, Jan 25, 2010, in forum: Perl Misc
    Replies:
    14
    Views:
    188
    John Bokma
    Jan 27, 2010
  5. Marius Gavrilescu

    Re: use strict; use warnings;

    Marius Gavrilescu, Feb 24, 2014, in forum: Perl Misc
    Replies:
    152
    Views:
    604
    $Bill
    Mar 11, 2014
Loading...

Share This Page