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

Dear Monks, This is my first posting to perlmonks.org. Please forgive me my ignorance or any transgressions. My question is about the correct use of "our()" within Perl modules. From http://perldoc.perl.org/functions/our.html it seems like if I declare an "our()" variable in a Perl module, that the simple variable name should be visible from other files that use the library. For example, if I have the following module "junk.pm":
package Mylib; use strict; use warnings; our $variable1 = "string1";
and put the following in "junk.pl":
use lib 'F:/scripts/perl/'; use junk; use strict; use warnings; print("\$variable1 = $variable1\n");
it seems from the above article that I should be able to access $variable1 without the "Mylib::" package name....but when I check the syntax, I get the following:
F:\scripts\perl>perl -c junk.pl Global symbol "$variable1" requires explicit package name at junk.pl l +ine 10. junk.pl had compilation errors.
Any idea where my thinking or implementation is wrong? Thank you, memnoch

Replies are listed 'Best First'.
Re: How to use "our()" variables correctly within a Perl module
by ikegami (Patriarch) on Nov 27, 2007 at 15:52 UTC

    While not totally accurate, a convenient way of thinking of our is as a lexically-scoped "no strict;" for specific variables.

    our is lexically scoped, so its effect will end at the end of Mylib.pm. From that point on, you'll have to refer to $Mylib::$variable1 as $Mylib::$variable1 unless you use some other method of aliasing $variable1 to $Mylib::$variable1.

    print("\$variable1 = $Mylib::variable1\n"); # OK
    use Mylib qw( $variable1 ); # If Mylib exports $variable1 print("\$variable1 = $variable1\n"); # OK
    our $variable1; local *variable1 = \$Mylib::variable1; # Create an alias. print("\$variable1 = $variable1\n"); # OK
    use Data::Alias qw( alias ); alias my $variable1 = $Mylib::variable1; # Create an alias. print("\$variable1 = $variable1\n"); # OK
      Thank you ikegami....I hadn't realized that the effect would end at the end of Mylib.pm. memnoch
Re: How to use "our()" variables correctly within a Perl module
by moritz (Cardinal) on Nov 27, 2007 at 15:47 UTC
    You declare the variable, but you don't import it into junk.pl's namespace. Printing $Mylib::varaible1 should work.

    For more details, see Exporter.

      Thank you moritz....I'll look into that. memnoch
Re: How to use "our()" variables correctly within a Perl module
by shmem (Chancellor) on Nov 27, 2007 at 20:26 UTC
    Any idea where my thinking or implementation is wrong?

    That's simple. You have declared the variable as our in your module, but not in your script using that module. For something to be labelled as our, there must be at least two of them sharing it. So, saying

    use lib 'F:/scripts/perl/'; use junk; use strict; use warnings; our $variable1; print("\$variable1 = $variable1\n");

    will fix that issue.

    Note that our variables are lexical aliases for a package variable. So, if the lexical scope spans several packages in the same file, all of those packages see that (unqualified) variable, which is a global to the package that declared it (I think of our as an autovivification of package globals):

    use strict; package Foo; our $bar = "guggug!\n"; package main; print $bar; __END__ guggug!
    Here $bar is visible from main just as $bar although it's typeglob lives in package Foo as $Foo::bar. Note that this behavior is different from what use vars does, so the vars pragma is not obsoleted by the introduction of our, contrary to what the docs state.

    --shmem

    _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                  /\_¯/(q    /
    ----------------------------  \__(m.====·.(_("always off the crowd"))."·
    ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
      Thank you shmem.....I tried your suggestion, but I get:
      F:\scripts\perl>perl -c junk.pl junk.pl syntax OK F:\scripts\perl>junk.pl Use of uninitialized value in concatenation (.) or string at F:\script +s\perl\junk.pl line 12. $variable1 = F:\scripts\perl>
      Any ideas? Thank you...memnoch
        Oops... ah well. Yes, I have ideas, and to correct myself where I've been wrong, and further elaborate in what I have been right - in junk.pl:
        #!/usr/bin/perl use junk; use strict; use warnings; package Mylib; our $variable1; package main; print("\$variable1 = $variable1\n"); __END__ $variable1 = string1

        That package switching creates a lexical (file scoped) alias to $Mylib::variable1, which is accessible in package main.

        Whithout that switching, an alias to $main::variable1 is created, which isn't related to the package global $Mylib::variable1 created by declaring our $variable1 in package Mylib.

        --shmem

        _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                      /\_¯/(q    /
        ----------------------------  \__(m.====·.(_("always off the crowd"))."·
        ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}