"Variable ... is not imported..." using an imported variable from a module

Discussion in 'Perl Misc' started by Volker Nicolai, Jul 1, 2005.

  1. Hi,

    I have read a lot about use strict and the visibility of variables
    but still can not understand why my following problem occurs:
    I have this small script:
    -------------------------------------------
    #!/usr/local/bin/perl

    #use strict; # _1_
    use import_pack;
    # use vars qw($p_hash); # _2_
    # *p_hash = \%main::p_hash; # _3_

    # print "P_HASH: $::p_hash{x} , $::p_hash{y}\n"; # _4_
    print "P_HASH: $p_hash{x} , $p_hash{y}\n"; # _5_

    -------------------------------------------
    and the module import_pack.pm:
    -------------------------------------------
    #!/usr/local/bin/perl

    use Exporter;

    @ISA = qw(Exporter);
    @EXPORT = qw(%p_hash);

    %p_hash = (
    x => 123,
    y => 888,
    );

    1;
    -------------------------------------------

    If I run it without use stricts it is fine.
    But if I use strict (_1_) then I need line _4_* instead of _5_,
    otherwise I get:
    Variable "%p_hash" is not imported at import_test.pl line 9
    Neither the 'announcement' of %p_hash with line _2_* nor the typeglob
    line _3_* helps and I don't have any idea why. I thought the typeglob must be
    pretty much the same as using the full var name (with package) in the
    print statement.
    So where is the crux?
    (* uncommented :)

    Thanks for helping!
    Volker
    Volker Nicolai, Jul 1, 2005
    #1
    1. Advertising

  2. Volker Nicolai

    Paul Lalli Guest

    Re: "Variable ... is not imported..." using an imported variable from a module

    Volker Nicolai wrote:
    > Hi,
    >
    > I have read a lot about use strict and the visibility of variables
    > but still can not understand why my following problem occurs:
    > I have this small script:
    > -------------------------------------------
    > #!/usr/local/bin/perl
    >
    > #use strict; # _1_
    > use import_pack;
    > # use vars qw($p_hash); # _2_
    > # *p_hash = \%main::p_hash; # _3_
    >
    > # print "P_HASH: $::p_hash{x} , $::p_hash{y}\n"; # _4_
    > print "P_HASH: $p_hash{x} , $p_hash{y}\n"; # _5_


    strict is in place here. All package variables must be fully
    qualified. Thus, you get a syntax error trying to use %main::p_hash
    without fully qualifiying it.

    >
    > -------------------------------------------
    > and the module import_pack.pm:
    > -------------------------------------------
    > #!/usr/local/bin/perl
    >
    > use Exporter;
    >
    > @ISA = qw(Exporter);
    > @EXPORT = qw(%p_hash);
    >
    > %p_hash = (
    > x => 123,
    > y => 888,
    > );


    strict is not in place here. Thus, you are allowed to use
    %main::p_hash without fully qualifying it.

    >
    > 1;
    > -------------------------------------------
    >
    > If I run it without use stricts it is fine.


    Correct. Without strictures, the main script is allowed to use
    %main::p_hash without fully qualifying.

    > But if I use strict (_1_) then I need line _4_* instead of _5_,
    > otherwise I get:
    > Variable "%p_hash" is not imported at import_test.pl line 9


    Correct. %p_hash is not imported. Because your .pm file is in package
    main::, whereas the 'use import_pack;' statement attempts to import
    from package import_pack::.

    > Neither the 'announcement' of %p_hash with line _2_* nor the typeglob
    > line _3_* helps and I don't have any idea why.


    The "announcement" fails because you attempted to "announce" $p_hash
    rather than %p_hash. Two wholly unrelated variables. If you change
    that to:
    use vars qw(%p_hash);
    or, preferably:
    our %p_hash;
    The code will execute as expected.

    Hope this makes sense.
    Paul Lalli
    Paul Lalli, Jul 1, 2005
    #2
    1. Advertising

  3. * Volker Nicolai schrieb:
    >
    > I have read a lot about use strict and the visibility of variables
    > but still can not understand why my following problem occurs:
    >
    > I have this small script:
    > -------------------------------------------
    > #!/usr/local/bin/perl
    > #use strict;
    > use import_pack;
    > print "P_HASH: $p_hash{x} , $p_hash{y}\n";
    > -------------------------------------------
    >
    > and the module import_pack.pm:
    > -------------------------------------------
    > #!/usr/local/bin/perl
    > use Exporter;
    > @ISA = qw(Exporter);
    > @EXPORT = qw(%p_hash);
    > %p_hash = (
    > x => 123,
    > y => 888,
    > );
    > 1;
    > -------------------------------------------


    Well, you know you should use strict. But please do it in your modules
    too. After doing so, you have to declare your vars used in your module.
    But remember to declare each var you want to export with our() instead
    of my() -- better yet: each var you want to access from outside. Btw, I
    don't see a declaration of your package in that package. I'd write it as
    something like:


    #!/usr/local/bin/perl -w

    package import_pack;
    use strict;
    use Exporter;

    our @ISA = qw(Exporter);
    our @EXPORT = qw(%p_hash);

    our %p_hash = (
    x => 123,
    y => 888,
    );

    1;
    __END__


    >
    > If I run it without use stricts it is fine.
    > But if I use strict [...] I get:
    > Variable "%p_hash" is not imported at [...]
    > So where is the crux?


    I suggest to fix your module first. To understand the error message you
    have to know what use() is doing (see `perldoc -f use`). In short, it
    require()s the file and tries to call import() from the package. The
    latter is your problem. It's not possible to call import_pack->import()
    since there is no package called "import_pack". It is just part of the
    file's name and that is not what Perl uses as the default package name.
    The default package is called "main", and all you have done in the file
    "import_pack.pm" is done in package "main" though.

    Your script is running fine with stricts if you only add the declaration
    of the package's name in your package file. But familiarize yourself
    with using strict in your modules too. My example above shows you what
    you need for that. Btw, our() creates exactly the same type of globals
    as you would do without any declaration under "no strict", but it has
    the same scoping rules as a declaration with my(). Please read `perldoc
    -f our` for details.

    regards,
    fabian
    Fabian Pilkowski, Jul 1, 2005
    #3
  4. Re: "Variable ... is not imported..." using an imported variablefrom a module

    Fabian Pilkowski wrote:

    [ In the context of an example .pm file ]

    > #!/usr/local/bin/perl -w


    There's no shebang line in a module.

    > package import_pack;
    > use strict;


    You forgot use warnings. Probably because you thought the shebang line
    would do it.
    Brian McCauley, Jul 1, 2005
    #4
  5. * Brian McCauley schrieb:
    > Fabian Pilkowski wrote:
    >
    > [ In the context of an example .pm file ]
    >
    >> #!/usr/local/bin/perl -w

    >
    > There's no shebang line in a module.


    You're right. But it is not disallowed to put a comment in the first
    line of a module file. It was just a silly thing to let this comment
    looking like a shebang line ... ;-)

    >
    >> package import_pack;
    >> use strict;

    >
    > You forgot use warnings. Probably because you thought the shebang line
    > would do it.


    Yes, that's what I thought. I mistaked perl modules for perl scripts in
    this case.

    thanks for correcting,
    fabian
    Fabian Pilkowski, Jul 1, 2005
    #5
  6. Volker Nicolai

    Peter Scott Guest

    On Fri, 01 Jul 2005 07:04:28 -0700, Volker Nicolai wrote:
    > #!/usr/local/bin/perl
    >
    > #use strict; # _1_
    > use import_pack;
    > # use vars qw($p_hash); # _2_
    > # *p_hash = \%main::p_hash; # _3_
    >
    > # print "P_HASH: $::p_hash{x} , $::p_hash{y}\n"; # _4_
    > print "P_HASH: $p_hash{x} , $p_hash{y}\n"; # _5_
    >
    > -------------------------------------------
    > and the module import_pack.pm:
    > -------------------------------------------
    > #!/usr/local/bin/perl
    >
    > use Exporter;
    >
    > @ISA = qw(Exporter);
    > @EXPORT = qw(%p_hash);
    >
    > %p_hash = (
    > x => 123,
    > y => 888,
    > );
    >
    > 1;
    > -------------------------------------------
    >
    > If I run it without use stricts it is fine.
    > But if I use strict (_1_) then I need line _4_* instead of _5_,
    > otherwise I get:
    > Variable "%p_hash" is not imported at import_test.pl line 9


    This is one of the most confusing messages this side of "... will not stay
    shared..."

    It is worth noting that you could get the same message with just this
    script and no modules:

    #!/path/to/perl
    use strict;
    %main::p_hash = ();
    print $p_hash{x};

    When perl gets to the last line, it sees a variable with no package
    qualifier. Since strict vars is in effect, it looks to see if it's
    a lexical, or permitted by use vars, or if it's $a/$b, etc - no dice on
    any of those - or if it's imported into the current package.

    You did no import, though. Because "use import_pack" is a compile time
    "require import_pack" followed by "import_pack->import", and you had no
    package called "import_pack", there was no call to Exporter->import.

    At this point, perl is going to complain about the unqualified variable,
    but it tries to be helpful and looks to see if there's a package variable
    with the same name that isn't imported (this isn't quite what the flow of
    control is intended to do but the effect is the same). Since you set
    %p_hash in main:: (in a separate scope where strict wasn't enabled, thus
    letting you get away with it), perl finds that and helpfully suggests that
    you're referring to the wrong imported variable.

    If all this is too confusing, just remember to set strict in all files and
    for the target of a use statement to begin with a package declaration of
    the same name (especially if it's using the Exporter).

    --
    Peter Scott
    http://www.perlmedic.com/
    http://www.perldebugged.com/
    Peter Scott, Jul 2, 2005
    #6
  7. Re: "Variable ... is not imported..." using an imported variable from a module

    "Paul Lalli" <> wrote in message
    > > Neither the 'announcement' of %p_hash with line _2_* nor the typeglob
    > > line _3_* helps and I don't have any idea why.

    >
    > The "announcement" fails because you attempted to "announce" $p_hash
    > rather than %p_hash. Two wholly unrelated variables. If you change
    > that to:
    > use vars qw(%p_hash);
    > or, preferably:
    > our %p_hash;
    > The code will execute as expected.
    >
    > Hope this makes sense.
    > Paul Lalli


    Thanks, Paul, especially that you made me see this stupid mistake.

    But if this
    > Correct. %p_hash is not imported. Because your .pm file is in package
    > main::, whereas the 'use import_pack;' statement attempts to import
    > from package import_pack::.
    >

    is true, why does it work after the correction ($p_hash -> %p_hash) ??
    The package name is still 'wrong' then. It looks to me that it is not
    mandatory that a module's file and package name are identical or how
    could I interpret that?
    (Despite this is written in "Programming Perl")
    Volker Nicolai, Jul 4, 2005
    #7
  8. Fabian Pilkowski <-marburg.de> wrote in message news:<>...
    > Well, you know you should use strict. But please do it in your modules
    > too. After doing so, you have to declare your vars used in your module.
    > But remember to declare each var you want to export with our() instead
    > of my() -- better yet: each var you want to access from outside. Btw, I
    > don't see a declaration of your package in that package. I'd write it as
    > something like:
    >
    >
    > #!/usr/local/bin/perl -w
    >
    > package import_pack;
    > use strict;
    > use Exporter;
    >
    > our @ISA = qw(Exporter);
    > our @EXPORT = qw(%p_hash);
    >
    > our %p_hash = (
    > x => 123,
    > y => 888,
    > );
    >
    > 1;
    > __END__
    >
    >
    > >
    > > If I run it without use stricts it is fine.
    > > But if I use strict [...] I get:
    > > Variable "%p_hash" is not imported at [...]
    > > So where is the crux?

    >
    > I suggest to fix your module first. To understand the error message you
    > have to know what use() is doing (see `perldoc -f use`). In short, it
    > require()s the file and tries to call import() from the package. The
    > latter is your problem. It's not possible to call import_pack->import()
    > since there is no package called "import_pack". It is just part of the
    > file's name and that is not what Perl uses as the default package name.
    > The default package is called "main", and all you have done in the file
    > "import_pack.pm" is done in package "main" though.
    >
    > Your script is running fine with stricts if you only add the declaration
    > of the package's name in your package file. But familiarize yourself
    > with using strict in your modules too. My example above shows you what
    > you need for that. Btw, our() creates exactly the same type of globals
    > as you would do without any declaration under "no strict", but it has
    > the same scoping rules as a declaration with my(). Please read `perldoc
    > -f our` for details.
    >
    > regards,
    > fabian


    Thanks to you too, Fabian, but why does it work after I have corrected the
    error, Paul Lalli has found - this works with the old module, without
    any name space change by package...
    ---------------------------------------
    #!/usr/local/bin/perl

    use strict;
    use import_pack;
    use vars qw(%p_hash);

    print "P_HASH: $p_hash{x} , $p_hash{y}\n";
    ---------------------------------------

    Please also see my answer to Paul (the name space change seem to not be
    mandatory).
    Volker Nicolai, Jul 4, 2005
    #8
  9. Re: "Variable ... is not imported..." using an imported variable from a module

    * Volker Nicolai schrieb:
    > "Paul Lalli" <> wrote in message
    >
    >> Correct. %p_hash is not imported. Because your .pm file is in package
    >> main::, whereas the 'use import_pack;' statement attempts to import
    >> from package import_pack::.
    >>

    > is true, why does it work after the correction ($p_hash -> %p_hash) ??
    > The package name is still 'wrong' then. It looks to me that it is not
    > mandatory that a module's file and package name are identical or how
    > could I interpret that?


    When doing it this way, there is no other package than "main" involved.
    Sure, you has a second file (import_pack.pm) but all the code therein is
    written as part of package "main". All the exporting stuff is senseless
    then, because it will set @main::ISA, @main::EXPORT and %main::p_hash
    directly. Try out to miss out the lines

    use Exporter;
    @ISA = qw(Exporter);
    @EXPORT = qw(%p_hash);

    in your "import_pack.pm". That is, what you really do in this case. This
    is what Paul has written: "%p_hash is not imported. Because your .pm
    file is in package main::, [...]".

    When using another package (that is only if you have the "package" line
    in your code) you're creating the desired vars @import_pack::ISA,
    @import_pack::EXPORT and %import_pack::p_hash. And because of using
    "Exporter" this %import_pack::p_hash is exported into package "main". I
    thought you want using Exporter.pm since you've written "use Exporter".

    Fimally, *you* have to decide what *you* really want.

    regards,
    fabian
    Fabian Pilkowski, Jul 4, 2005
    #9
  10. * Volker Nicolai schrieb:
    >
    > Thanks to you too, Fabian, but why does it work after I have corrected the
    > error, Paul Lalli has found - this works with the old module, without
    > any name space change by package...


    In Paul's version all the vars are settled in package "main", regardless
    in which file they are declared.

    >
    > Please also see my answer to Paul (the name space change seem to not be
    > mandatory).


    It is mandatory if you really want to export something. That is what I
    thought when reading your "use Exporter".

    Please also see my answer there.

    regards,
    fabian
    Fabian Pilkowski, Jul 4, 2005
    #10
    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. dody suria wijaya

    Get importer module from imported module

    dody suria wijaya, Feb 7, 2005, in forum: Python
    Replies:
    5
    Views:
    382
    dody suria wijaya
    Feb 8, 2005
  2. GinTon
    Replies:
    18
    Views:
    444
    jim-on-linux
    Nov 25, 2006
  3. kj
    Replies:
    9
    Views:
    286
    AK Eric
    Nov 12, 2009
  4. David
    Replies:
    2
    Views:
    524
    David
    Feb 11, 2010
  5. Dun Peal
    Replies:
    10
    Views:
    440
    Chris Rebert
    May 3, 2011
Loading...

Share This Page