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

How is it that I am able to see the unqualified $var variable from within the Bar package, as shown below (last line)?

#!/usr/bin/env perl use Modern::Perl; package Foo; our $var = 42; # This is $Foo::var. # Change the current package. package Bar; # This works, as expected. say "\$Foo::var: $Foo::var"; # But why does this work? $var is not in package Bar, # and we are in package Bar here. say "\$var: $var"; # !?
  • Comment on How is it that I can see this package variable from another package without fully-qualifying its name?
  • Download Code

Replies are listed 'Best First'.
Re: How is it that I can see this package variable from another package without fully-qualifying its name?
by chromatic (Archbishop) on Apr 24, 2011 at 07:30 UTC

    An our (see especially the first paragraph) binding respects scope—in this case, file scope.

      I don't know exactly what you mean when you say that an our binding "respects scope".

      I do see that the declaration and definition of $var is at file scope. My understanding is that "package Bar" changes the package from Foo to Bar. Maybe I'm confusing "change of package" with "change of scope"?

      I see that the following works as I'd expect:

      #!/usr/bin/env perl use Modern::Perl; { package Foo; our $var = 42; # This is $Foo::var. } { package Bar; # This works, as expected. say "\$Foo::var: $Foo::var"; #say "\$var: $var"; # Fails, as expected. } #say "\$var: $var"; # Fails, as expected. say "\$Foo::var: $Foo::var";

      Does that look like the correct way to keep packages separate in a single file?

      (I realize that everything would also work as expected if I kept each package in its own module. And it would make them easily testable as well.)

        Maybe I'm confusing "change of package" with "change of scope"?

        Exactly! The package keyword doesn't introduce a new scope for my or our bindings. Only a new file or curly braces do.

        Keeping each package in a separate file is generally the best approach, but using curly braces to isolate packages works well too. Perl 5.14 has a new package NAME { ... } syntax to make this even easier.

Re: How is it that I can see this package variable from another package without fully-qualifying its name?
by tchrist (Pilgrim) on Apr 24, 2011 at 20:07 UTC
    You aren’t, because it isn’t a package variable. As the documentation says, an our declaration creates a lexically scoped alias to a package variable. That alias is of course tied therefore to a scope, not to a package.

    Since it is lexically scoped, there is no reason that changing the default prefix used for global variables — read, the package — should have anything at all to do with changing scope. Scoped variables are completely different, since they have no package prefix.

Re: How is it that I can see this package variable from another package without fully-qualifying its name?
by LanX (Saint) on Apr 24, 2011 at 20:50 UTC
Re: How is it that I can see this package variable from another package without fully-qualifying its name?
by John M. Dlugosz (Monsignor) on Apr 24, 2011 at 11:17 UTC
    Please: it's its, not it's in the title!

    Here's a good way to remember it: qw/his hers its/ none of them have apostrophes in them. Whenever you see "it's" mentally expand it into "it is", since that's what it always is.

      Arg! Can't believe I did that. I get it right almost all of the time, but sometimes it still manages to trick me: "Joe's bar and grill, Larry's language, it's scope ... {sigh}"

        If you logged in rather than posting as Anonymous, you could edit it and fix it after you see it. That bugs me more than the mistake itself; the fact that it's cast in stone forever now.

        So, how about signing up and getting your own user name?

        "Joe's bar and grill, Larry's language, it's scope ... {sigh}
        Because you are mixing proper nouns and pronouns. A better way to remember is Hi's bar a grill, he'r language, it's scope... er, huh? His/her/its form a set.