Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much

Unusual variable declaration

by davies (Prior)
on Nov 02, 2019 at 21:31 UTC ( #11108262=perlquestion: print w/replies, xml ) Need Help??

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

our $var; *var = \$main::var;

I have recently come across the construct above, which is unfamiliar to me. "our" is reasonably clear (although I have made mistakes using it in the past so I may not know it as well as I think), but in combination with the second line, I am not sure what is going on. Could someone please point me to the relevant docs?


John Davies

Replies are listed 'Best First'.
Re: Unusual variable declaration
by choroba (Bishop) on Nov 02, 2019 at 21:46 UTC
    The first line declares an alias $var for the global variable $var in the current package. The second line makes it an alias of the $var variable in the main package.

    Therefore, it only makes sense to use this in a package different to main. For example:

    #!/usr/bin/perl use warnings; use strict; our $var; $var = 42; { package My; our $var; *var = \$main::var; print $var, "\n"; $var = 84; } print $var, "\n";

    map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]

      • local

      I almost always use this construct with local except if I want to alias globally.

       local *var = \$main::var;  

      Otherwise any later use of $My::var in another scope will also be aliased.

      • importing

      Should also be mentioned that typeglob aliasing is the essential underlying mechanism Exporter is using.

      Though mostly for subs not vars and always globally.

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

      Exactly what I was going to say :-) The most relevant docs are probably perlmod.

Re: Unusual variable declaration
by davido (Cardinal) on Nov 02, 2019 at 21:50 UTC

    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.


      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!

      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


        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."


Re: Unusual variable declaration
by BillKSmith (Prior) on Nov 03, 2019 at 00:29 UTC
    The Perl feature which you do not recognize is called a "typeglob". The formal documentation for this feature is not easy to find without the link Symbol Tables provided by haukex. I have found a much better explanation in the rather old book "Object Oriented Perl" (ISBN 1884777790).

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://11108262]
Front-paged by haukex
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others exploiting the Monastery: (9)
As of 2019-11-18 21:32 GMT
Find Nodes?
    Voting Booth?
    Strict and warnings: which comes first?

    Results (92 votes). Check out past polls.