http://qs321.pair.com?node_id=11108265


in reply to Unusual variable declaration

our $var; # Declare a variable in the current package. *var = \$main::var; # Create an alias in the current package to packag +e main's $var;

Observe the following:

package Foo; our $var = 42; print __PACKAGE__, ": $var\n"; print \$var, "\n"; package main; *var = \$Foo::var; print __PACKAGE__, ": $var\n"; print \$var, "\n";

The output:

Foo: 42 SCALAR(0x559ec7e7b6a0) main: 42 SCALAR(0x559ec7e7b6a0)

This is aliasing; you're creating in main a symbol that refers to the same variable that is known in Foo as $var. Notice they share the same memory address. (It will be a different address on your system).

In your example code you were creating $var in the current package and aliasing it to $main::var (the $var that belongs to main::). The example I gave is going in the opposite direction because it's easier to demonstrate. But the concept is the same; you're setting up a symbol that refers to the same thing that is known in another package namespace simultaneously.

This is what Exporter does.


Dave

Replies are listed 'Best First'.
Re^2: Unusual variable declaration
by Jenda (Abbot) on Nov 04, 2019 at 12:37 UTC

    I would not call that "declaring a variable". my $var declares a variable.

    our $var; merely instructs perl to allow you to access the global variable $<current_package>::var using the short name. No new variable gets created.

    package Foo; $Foo::var = 1; print "package var is $Foo::var\n"; { our $var; print "same variable using short name is $var\n"; $var = 2; print "using short name changed to $var\n"; print "package var is now $Foo::var\n"; } print "I said package var is now $Foo::var\n"; $Foo::var = 3; print "And now it's $Foo::var\n"; { our $var; print "still the same variable using short name is $var\n"; }

    If it were my instead of <our> not only you would not access the package variable $Foo:var, but you'd also declare two separate variables in those two blocks!

    Jenda
    1984 was supposed to be a warning,
    not a manual!

      Yes and no ... the definitions vary.

      What's happening is declaration, allocation and initialization.

      You are right that our $var declares a "lexical alias" to $__PACKAGE__:var

      But if this is the first use of the package variable it'll also allocate memory and initialize the value at runtime (which is undef if not assigned otherwise)

      I.o.W. I doubt that the slot of the typeglob will be populated before, hence I'd call this a full declaration.

      I suppose the terminology "declaration" stems from statically typed languages and needs to be properly redefined here.

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      Wikisyntax for the Monastery FootballPerl is like chess, only without the dice

      update

      I didn't check the implementation details, so the timing between compile and run-time might slightly differ.

      You are not wrong in the details of what our accomplishes. But it is referred to as a declaration in the documentation for our:

      An our declaration declares an alias for a package variable that will be visible across its entire lexical scope, even across package boundaries. The package in which the variable is entered is determined at the point of the declaration, not at the point of use.

      Fortunately it does what it does regardless of what we call the behavior. :) It might be a case where there's not a one or few word name for the action our takes. But I do acknowledge your point; our is not a declaration in the say way that my is, or even int foo; in C. It would be nice if we had a word for it that isn't "relax the requirement for fully qualifying the name within a lexical scope under strict."


      Dave

        > our is not a declaration in the say way that my is

        Why?

        My is creating a pad entry for a lexically scoped variable, allocating and initializing it.

        A pad is a symbol table in a hash structure similar to a stash.

        Our is basically doing the same thing, apart from skipping to allocate space if the variable already exists.

        My's destruction at the end of scope is hardly a criterion for declaration.

        The pad is private, the stash is public and global. That's the basic difference.

        Cheers Rolf
        (addicted to the Perl Programming Language :)
        Wikisyntax for the Monastery FootballPerl is like chess, only without the dice