Softpanorama

May the source be with you, but remember the KISS principle ;-)
Home Switchboard Unix Administration Red Hat TCP/IP Networks Neoliberalism Toxic Managers
(slightly skeptical) Educational society promoting "Back to basics" movement against IT overcomplexity and  bastardization of classic Unix

Perl our variables

News

Best Books

Recommended Links  Perl state variables  Perl our variables My Variables Local variables

Debugging

Namespaces Table of Contents           Perl Regular Expressions

 

Libraries

Perl modules

Perl Warts

Perl philosophy and history Tips Humor Etc

This type of variables was introduced into language in order to deal with problems coursed by usage strict pragma, which prohibits using global variables without qualifying them with the  namespace.

In essence our variable is an alias to a pre-existing global variable. They allow more convenient notation for variables that are placed in the main namespace , but that's about it. 

Our variables are aliases that allow to use package global variables without prefixing them with $::. They aren't globally-scoped, but lexically-scoped aliases to global variables. Lexical scope makes them similar to  my variables but here  the analogy ends. 

This is not a new variable that exists in the subroutine or module namespace. This is just a notation for re-using variable from global (main::) namespace without  prefixing it them each time. Declaring our $VERSION  allows you to use the global variable  $::VERSION and avoid complaining about it from pragma use strict  or use strict "vars".

As they are for use within the current lexical scope they can also can be understood as implicit "import" of global variables name into local scope.  

our - perldoc.perl.org

Here is the explanation from 'our' is not 'my'

Many people misunderstand how our is used and I've often seen code where it's used as a synonym for my. This is not the case and I hope this clears up some of the differences. I'm posting this because I've run across this a few times lately and I thought I should just 'get it out there' for others.

There are basically two ways of declaring variables in Perl: global and lexical. A global variable has a package name prepending to it:

$main::foo;

$CGI::POST_MAX;

@foo::bar;

[download]

All packages can access the variable $foo in the main symbol table (%main:: or the shorthand %::) by using $main::foo. Global variables are generally a bad idea, but do crop up in a lot of code.

A lexically scoped variable is declared with my:

my $foo;

my $POST_MAX;

my @bar;

[download]

Though they look similar to the package variables above, they are not the same and cannot be accessed outside of the scope in which they were declared.

If you use strict and you try to access a variable that's not previously declared, you'll get an error similar to the following:

Global symbol "$foo" requires explicit package name at C:\test.pl +line 2.

[download]

Basically, Perl expects that you are trying to use a package variable, but left off the package name.

The problem with using package names ($main::foo) is that strict ignores these variables and if you type $main::field in one place and $main::feild in another place, strict won't warn you of the typo.

our tries to help out by letting you use package variables without adding the package name. The following two variables are the same:

package foo;

use strict;

our $bar; # These are the same as $foo::bar;

[download]

That eliminates the $main::field problem by allowing you to do this:

our $field;

[download]

From there, you just drop package names and the script will run and later Perl will kill the script if you try use $feild.

It is important to understand that our is lexically scopes and "can cross package  lines"

[/msg]
Re: 'our' is not 'my'
by ikegami (Pope) on Oct 26, 2007 at 12:02 UTC

    There is a catch with our that doesn't exist with use vars:

    package AA; $AA::var = __PACKAGE__; our $var; print "$var\n"; package BB; $BB::var = __PACKAGE__; print "$var\n"; # Prints 'AA'.

    [download]

    Using curlies when using multiple packages in one file avoids the problem.

    { package AA; $AA::var = __PACKAGE__; our $var; print "$var\n"; } { package BB; $BB::var = __PACKAGE__; print "$var\n"; # Compile error! }

    [download]

    Keeping that exception in mind, our is like no strict 'vars'; on a per-var basis.

        I prefer to think of our as the equivalent of no strict 'vars' for a single variable, but in reality, our creates a lexically-scoped variable aliased to a package variable.

        In effect,
        our $var;
        is the same as
        use Data::Alias;
        alias my $var = $__PACKAGE__::var;
        (Syntax issues aside.)

        Unlike blocks and files, packages aren't lexical scopes. Switching package neither destroys the our variable (because the our variable is lexically scoped) nor change to which package variable the our variable is aliased (because package doesn't know anything about the our variable).

        Re: 'our' is not 'my'
        by Tabari (Monk) on Oct 26, 2007 at 11:55 UTC
          I was cleaning up some old code which did not use strict.
          As it used a lot of global vars, I was forced to use our, the way you explained. I didn't know the exact meaning before
          Tabari

Top Visited
Switchboard
Latest
Past week
Past month

NEWS CONTENTS

Old News ;-)

[Nov 23, 2019] Static local variables in Perl

Jan 01, 2012 | stackoverflow.com

Ask Question Asked 7 years, 5 months ago Active 2 years, 8 months ago Viewed 12k times


Charles , 2012-05-31 20:50:19

I'm looking for advice on Perl best practices. I wrote a script which had a complicated regular expression:
my $regex = qr/complicated/;

# ...

sub foo {
  # ...

  if (/$regex/)
  # ...
}

where foo is a function which is called often, and $regex is not used outside that function. What is the best way to handle situations like this? I only want it to be interpreted once, since it's long and complicated. But it seems a bit questionable to have it in global scope since it's only used in that sub. Is there a reasonable way to declare it static?

A similar issue arises with another possibly-unjustified global. It reads in the current date and time and formats it appropriately. This is also used many times, and again only in one function. But in this case it's even more important that it not be re-initialized, since I want all instances of the date-time to be the same from a given invocation of the script, even if the minutes roll over during execution.

At the moment I have something like

my ($regex, $DT);

sub driver {
  $regex = qr/complicated/;
  $DT = dateTime();
  # ...
}

# ...

driver();

which at least slightly segregates it. But perhaps there are better ways.

Again: I'm looking for the right way to do this, in terms of following best practices and Perl idioms. Performance is nice but readability and other needs take priority if I can't have everything.

hobbs ,

If you're using perl 5.10+, use a state variable.
use feature 'state';
# use 5.010; also works

sub womble {
    state $foo = something_expensive();
    return $foo ** 2;
}

will only call something_expensive once.

If you need to work with older perls, then use a lexical variable in an outer scope with an extra pair of braces:

{
    my $foo = something_expensive();
    sub womble {
        return $foo ** 2;
    }
}

this keeps $foo from leaking to anyone except for womble .

ikegami , 2012-05-31 21:14:04

Is there any interpolation in the pattern? If not, the pattern will only be compiled once no matter how many times the qr// is executed.
$ perl -Mre=debug -e'qr/foo/ for 1..10' 2>&1 | grep Compiling | wc -l
1

$ perl -Mre=debug -e'qr/foo$_/ for 1..10' 2>&1 | grep Compiling | wc -l
10

Even if there is interpolation, the pattern will only be compiled if the interpolated variables have changed.

$ perl -Mre=debug -e'$x=123; qr/foo$x/ for 1..10;' 2>&1 | grep Compiling | wc -l
1

$ perl -Mre=debug -e'qr/foo$_/ for 1..10' 2>&1 | grep Compiling | wc -l
10

Otherwise, you can use

{
   my $re = qr/.../;
   sub foo {
      ...
      /$re/
      ...
   }
}

or

use feature qw( state );
sub foo {
   state $re = qr/.../;
   ...
   /$re/
   ...
}

Alan Rocker , 2014-07-02 16:25:27

Regexes can be specified with the "o" modifier, which says "compile pattern once only" - in the 3rd. edition of the Camel, see p. 147

zoul ,

There's a state keyword that might be a good fit for this situation:
sub foo {
    state $regex = /.../;
    ...
}

TrueY , 2015-01-23 10:14:12

I would like to complete ikegami 's great answer. Some more words I would like to waste on the definition of local variables in pre 5.10 perl .

Let's see a simple example code:

#!/bin/env perl 

use strict;
use warnings;

{ # local 
my $local = "After Crying";
sub show { print $local,"\n"; }
} # local

sub show2;

show;
show2;

exit;

{ # local 
my $local = "Solaris";
sub show2 { print $local,"\n"; }
} # local

The user would expect that both sub will print the local variable, but this is not true!

Output:

After Crying
Use of uninitialized value $local in print at ./x.pl line 20.

The reason is that show2 is parsed, but the initialization of the local variable is not executed! (Of course if exit is removed and a show2 is added at the end, Solaris will be printed in the thirds line)

This can be fixed easily:

{ # local 
my $local;
BEGIN { $local = "Solaris"; }
sub show2 { print $local,"\n"; }
} # local

And now the output what was expected:

After Crying
Solaris

But state in 5.10+ is a better choice...

I hope this helps!

[Nov 14, 2019] perl - package variable scope in module subroutine

Nov 14, 2019 | stackoverflow.com

Asked 7 years, 7 months ago Active 7 years, 7 months ago Viewed 20k times 8 1


brian d foy ,Jul 17, 2014 at 17:54

How do I change the value of a variable in the package used by a module so that subroutines in that module can use it?

Here's my test case:

testmodule.pm:

package testmodule;

use strict;
use warnings;
require Exporter;

our ($VERSION, @ISA, @EXPORT, @EXPORT_OK, %EXPORT_TAGS);

@ISA = qw(Exporter);
@EXPORT = qw(testsub);

my $greeting = "hello testmodule";
my $var2;

sub testsub {
    printf "__PACKAGE__: %s\n", __PACKAGE__;
    printf "\$main::greeting: %s\n", $main::greeting;
    printf "\$greeting: %s\n", $greeting;
    printf "\$testmodule::greeting: %s\n", $testmodule::greeting;
    printf "\$var2: %s\n", $var2;
} # End testsub
1;

testscript.pl:

#!/usr/bin/perl -w
use strict;
use warnings;
use testmodule;

our $greeting = "hello main";
my $var2 = "my var2 in testscript";

$testmodule::greeting = "hello testmodule from testscript";
$testmodule::var2 = "hello var2 from testscript";

testsub();

output:

Name "testmodule::var2" used only once: possible typo at ./testscript.pl line 11.
__PACKAGE__: testmodule
$main::greeting: hello main
$greeting: hello testmodule
$testmodule::greeting: hello testmodule from testscript
Use of uninitialized value $var2 in printf at testmodule.pm line 20.
$var2:

I expected $greeting and $testmodule::greeting to be the same since the package of the subroutine is testmodule .

I guess this has something to do with the way use d modules are eval d as if in a BEGIN block, but I'd like to understand it better.

I was hoping to set the value of the variable from the main script and use it in the module's subroutine without using the fully-qualified name of the variable.

perl-user ,Sep 5, 2013 at 13:58

As you found out, when you use my , you are creating a locally scoped non-package variable. To create a package variable, you use our and not my :
my $foo = "this is a locally scoped, non-package variable";
our $bar = "This is a package variable that's visible in the entire package";

Even better:

{
   my $foo = "This variable is only available in this block";
   our $bar = "This variable is available in the whole package":
}

print "$foo\n";    #Whoops! Undefined variable
print "$bar\n";    #Bar is still defined even out of the block

When you don't put use strict in your program, all variables defined are package variables. That's why when you don't put it, it works the way you think it should and putting it in breaks your program.

However, as you can see in the following example, using our will solve your dilemma:

File Local/Foo.pm
#! /usr/local/bin perl
package Local::Foo;

use strict;
use warnings;
use feature qw(say);

use Exporter 'import';
our @EXPORT = qw(testme);

our $bar = "This is the package's bar value!";
sub testme {

    # $foo is a locally scoped, non-package variable. It's undefined and an error
    say qq(The value of \$main::foo is "$main::foo");

    # $bar is defined in package main::, and will print out
    say qq(The value of \$main::bar is "$main::bar");

    # These both refer to $Local::Foo::bar
    say qq(The value of \$Local::Foo::bar is "$Local::Foo::bar");
    say qq(The value of bar is "$bar");
}

1;
File test.pl
#! /usr/local/bin perl
use strict;
use warnings;
use feature qw(say);
use Local::Foo;

my $foo = "This is foo";
our $bar = "This is bar";
testme;

say "";
$Local::Foo::bar = "This is the NEW value for the package's bar";
testme

And, the output is:

Use of uninitialized value $foo in concatenation (.) or string at Local/Foo.pm line 14.
The value of $main::foo is ""
The value of $main::bar is "This is bar"
The value of $Local::Foo::bar is "This is the package's bar value!"
The value of bar is "This is the package's bar value!"

Use of uninitialized value $foo in concatenation (.) or string at Local/Foo.pm line 14.
The value of $main::foo is ""
The value of $main::bar is "This is bar"
The value of $Local::Foo::bar is "This is the NEW value for the package's bar"
The value of bar is "This is the NEW value for the package's bar"

The error message you're getting is the result of $foo being a local variable, and thus isn't visible inside the package. Meanwhile, $bar is a package variable and is visible.

Sometimes, it can be a bit tricky:

if ($bar -eq "one") {
   my $foo = 1;
}
else {
   my $foo = 2;
}

print "Foo = $foo\n";

That doesn't work because $foo only bas a value inside the if block. You have to do this:

my $foo;
if ($bar -eq "one") {
   $foo = 1;
}
else {
  $foo = 2;
}

print "Foo = $foo\n"; #This works!

Yes, it can be a bit to get your head wrapped around it initially, but the use of use strict; and use warnings; is now de rigueur and for good reasons. The use of use strict; and use warnings; probably has eliminated 90% of the mistakes people make in Perl. You can't make a mistake of setting the value of $foo in one part of the program, and attempting to use $Foo in another. It's one of the things I really miss in Python.

> ,

After reading Variable Scoping in Perl: the basics more carefully, I realized that a variable declared with my isn't in the current package. For example, in a simple script with no modules if I declare my $var = "hello" $main::var still doesn't have a value.

The way that this applies in this case is in the module. Since my $greeting is declared in the file, that hides the package's version of $greeting and that's the value which the subroutine sees. If I don't declare the variable first, the subroutine would see the package variable, but it doesn't get that far because I use strict .

If I don't use strict and don't declare my $greeting , it works as I would have expected. Another way to get the intended value and not break use strict is to use our $greeting . The difference being that my declares a variable in the current scope while our declares a variable in the current package .

[Oct 09, 2019] Static and state variables in Perl

Oct 09, 2019 | perlmaven.com

Prev Next In most of the cases we either want a variable to be accessible only from inside a small scope, inside a function or even inside a loop. These variables get created when we enter the function (or the scope created by a a block) and destroyed when we leave the scope.

In some cases, especially when we don't want to pay attention to our code, we want variables to be global, to be accessible from anywhere in our script and be destroyed only when the script ends. In General having such global variables is not a good practice.

In some cases we want a variable to stay alive between function calls, but still to be private to that function. We want it to retain its value between calls.

Are you serious about Perl? Check out my Beginner Perl Maven book .
I have written it for you!

In the C programming language one can designate a variable to be a static variable . This means it gets initialized only once and it sticks around retaining its old value between function calls.

In Perl, the same can be achieved using the state variable which is available starting from version 5.10, but there is a construct that will work in every version of Perl 5. In a way it is even more powerful.

Let's create a counter as an example:

state variable
  1. use strict ;
  2. use warnings ;
  3. use 5.010 ;
  4. sub count {
  5. state $counter = 0 ;
  6. $counter ++;
  7. return $counter ;
  8. }
  9. say count ();
  10. say count ();
  11. say count ();
  12. #say $counter;

In this example, instead of using my to declare the internal variable , we used the state keyword.

$counter is initialized to 0 only once, the first time we call counter() . In subsequent calls, the line state $counter = 0; does not get executed and $counter has the same value as it had when we left the function the last time.

Thus the output will be:

1
2
3

If we removed the # from last line, it would generate a Global symbol "$counter" requires explicit package name at ... line ... error when trying to compile the script. This just shows that the variable $counter is not accessible outside the function.

state is executed in the first call

Check out this strange example:

  1. use strict ;
  2. use warnings ;
  3. use 5.010 ;
  4. sub count {
  5. state $counter = say "world" ;
  6. $counter ++;
  7. return $counter ;
  8. }
  9. say "hello" ;
  10. say count ();
  11. say count ();
  12. say count ();

This will print out

hello
world
2
3
4

showing that the state $counter = say "world"; line only gets executed once. In the first call to count() say , which was also added in version 5.10 , will return 1 upon success.

static variables in the "traditional" way
  1. use strict ;
  2. use warnings ;
  3. use 5.010 ;
  4. {
  5. my $counter = 0 ;
  6. sub count {
  7. $counter ++;
  8. return $counter ;
  9. }
  10. }
  11. say count ();
  12. say count ();
  13. say count ();

This provides the same result as the above version using state , except that this could work in older versions of perl as well. (Especially if I did not want to use the say keyword, that was also introduced in 5.10.)

This version works because functions declarations are global in perl - so count() is accessible in the main body of the script even though it was declared inside a block. On the other hand the variable $counter is not accessible from the outside world because it was declared inside the block. Lastly, but probably most importantly, it does not get destroyed when we leave the count() function (or when the execution is outside the block), because the existing count() function still references it.

Thus $count is effectively a static variable.

First assignment time
  1. use strict ;
  2. use warnings ;
  3. use 5.010 ;
  4. say "hi" ;
  5. {
  6. my $counter = say "world" ;
  7. sub count {
  8. $counter ++;
  9. return $counter ;
  10. }
  11. }
  12. say "hello" ;
  13. say count ();
  14. say count ();
  15. say count ();
hi
world
hello
2
3
4

This shows that in this case too, the declaration and the initial assignment my $counter = say "world"; happens only once, but we can also see that the assignment happens before the first call to count() as if the my $counter = say "world"; statement was part of the control flow of the code outside of the block.

Shared static variable

This "traditional" or "home made" static variable has an extra feature. Because it does not belong to the the count() subroutine, but to the block surrounding it, we can declare more than one functions in that block and we can share this static variable between two or even more functions.

For example we could add a reset_counter() function:

  1. use strict ;
  2. use warnings ;
  3. use 5.010 ;
  4. {
  5. my $counter = 0 ;
  6. sub count {
  7. $counter ++;
  8. return $counter ;
  9. }
  10. sub reset_counter {
  11. $counter = 0 ;
  12. }
  13. }
  14. say count ();
  15. say count ();
  16. say count ();
  17. reset_counter ();
  18. say count ();
  19. say count ();
1
2
3
1
2

Now both functions can access the $counter variable, but still nothing outside the enclosing block can access it.

Static arrays and hashes

As of now, you cannot use the state declaration in list context. This means you cannot write state @y = (1, 1); . This limitation could be overcome by some extra coding. For example in this implementation of the Fibonacci series, we checked if the array is empty and set the default values:

  1. use strict ;
  2. use warnings ;
  3. use 5.010 ;
  4. sub fib {
  5. state @y ;
  6. @y = ( 1 , 1 ) if not @y ; # workaround initialization
  7. push @y , $y [ 0 ]+ $y [ 1 ];
  8. return shift @y ;
  9. }
  10. say fib ();
  11. say fib ();
  12. say fib ();
  13. say fib ();
  14. say fib ();

Alternatively we could use the "old-style" static variable with the enclosing block.

Here is the example generating the Fibonacci series:

  1. use strict ;
  2. use warnings ;
  3. use 5.010 ;
  4. {
  5. my @y = ( 1 , 1 );
  6. sub fib {
  7. push @y , $y [ 0 ]+ $y [ 1 ];
  8. return shift @y ;
  9. }
  10. }
  11. say fib ();
  12. say fib ();
  13. say fib ();
  14. say fib ();
  15. say fib ();

[Oct 09, 2019] use vars vs ours

Oct 09, 2019 | perlmaven.com

use vars

The problem is that use strict is complaining that there is a variable $x which is not declared with my and that it does not know about it. So we need a way to tell strict that it is ok. We know about the $x variable and we want to use it, but we want it to be a package variable. We don't want to declare it using my and we don't want to always prefix it with the package name.

With use vars ('$x') we can achieve that:

  1. use strict ;
  2. package VeryLongName ;
  3. use vars ( '$x' );
  4. $x = 23 ;
  5. print "VeryLongName: $x\n" ;

This works, but the documentation of vars tells us that the functionality provided by this pragma has been superseded by "our" declarations .

So how does our work?

our
  1. use strict ;
  2. package VeryLongName ;
  3. our $x = 23 ;
  4. print "VeryLongName: $x\n" ;
Caveat

The our declaration itself is lexically scoped, meaning it is limited by the file or by enclosing curly braces. In the next example we don't have curly braces and thus the declaration our $x = 23; will be intact even after switching namespaces. This can lead to very unpleasant situations. My recommendation is to avoid using our (you almost always need to use my anyway) and to put every package in its own file.

  1. use strict ;
  2. package VeryLongName ;
  3. our $x = 23 ;
  4. print "VeryLongName: $x\n" ; # VeryLongName: 23
  5. package main ;
  6. print "$x\n" ; # 23

[Oct 09, 2019] scope - What is the difference between my and our in Perl - Stack Overflow

Oct 09, 2019 | stackoverflow.com

Asked 10 years, 5 months ago Active 3 years, 1 month ago Viewed 107k times 180 56


Nathan Fellman ,May 10, 2009 at 10:24

I know what my is in Perl. It defines a variable that exists only in the scope of the block in which it is defined. What does our do? How does our differ from my ?

Nathan Fellman ,Nov 20, 2016 at 1:15

Great question: How does our differ from my and what does our do?

In Summary:

Available since Perl 5, my is a way to declare:


On the other hand, our variables are:


Declaring a variable with our allows you to predeclare variables in order to use them under use strict without getting typo warnings or compile-time errors. Since Perl 5.6, it has replaced the obsolete use vars , which was only file-scoped, and not lexically scoped as is our .

For example, the formal, qualified name for variable $x inside package main is $main::x . Declaring our $x allows you to use the bare $x variable without penalty (i.e., without a resulting error), in the scope of the declaration, when the script uses use strict or use strict "vars" . The scope might be one, or two, or more packages, or one small block.

Georg ,Oct 1, 2016 at 6:41

The PerlMonks and PerlDoc links from cartman and Olafur are a great reference - below is my crack at a summary:

my variables are lexically scoped within a single block defined by {} or within the same file if not in {} s. They are not accessible from packages/subroutines defined outside of the same lexical scope / block.

our variables are scoped within a package/file and accessible from any code that use or require that package/file - name conflicts are resolved between packages by prepending the appropriate namespace.

Just to round it out, local variables are "dynamically" scoped, differing from my variables in that they are also accessible from subroutines called within the same block.

Nathan Fellman ,Nov 20, 2015 at 18:46

An example:
use strict;

for (1 .. 2){
    # Both variables are lexically scoped to the block.
    our ($o);  # Belongs to 'main' package.
    my  ($m);  # Does not belong to a package.

    # The variables differ with respect to newness.
    $o ++;
    $m ++;
    print __PACKAGE__, " >> o=$o m=$m\n";  # $m is always 1.

    # The package has changed, but we still have direct,
    # unqualified access to both variables, because the
    # lexical scope has not changed.
    package Fubb;
    print __PACKAGE__, " >> o=$o m=$m\n";
}

# The our() and my() variables differ with respect to privacy.
# We can still access the variable declared with our(), provided
# that we fully qualify its name, but the variable declared
# with my() is unavailable.
print __PACKAGE__, " >> main::o=$main::o\n";  # 2
print __PACKAGE__, " >> main::m=$main::m\n";  # Undefined.

# Attempts to access the variables directly won't compile.
# print __PACKAGE__, " >> o=$o\n";
# print __PACKAGE__, " >> m=$m\n";

# Variables declared with use vars() are like those declared
# with our(): belong to a package; not private; and not new.
# However, their scoping is package-based rather than lexical.
for (1 .. 9){
    use vars qw($uv);
    $uv ++;
}

# Even though we are outside the lexical scope where the
# use vars() variable was declared, we have direct access
# because the package has not changed.
print __PACKAGE__, " >> uv=$uv\n";

# And we can access it from another package.
package Bubb;
print __PACKAGE__, " >> main::uv=$main::uv\n";

daotoad ,May 10, 2009 at 16:37

Coping with Scoping is a good overview of Perl scoping rules. It's old enough that our is not discussed in the body of the text. It is addressed in the Notes section at the end.

The article talks about package variables and dynamic scope and how that differs from lexical variables and lexical scope.

Chas. Owens ,Oct 7, 2013 at 14:02

my is used for local variables, where as our is used for global variables. More reading over Variable Scoping in Perl: the basics .

ruffin ,Feb 10, 2015 at 19:47

It's an old question, but I ever met some pitfalls about lexical declarations in Perl that messed me up, which are also related to this question, so I just add my summary here:

1. definition or declaration?

local $var = 42; 
print "var: $var\n";

The output is var: 42 . However we couldn't tell if local $var = 42; is a definition or declaration. But how about this:

use strict;
use warnings;

local $var = 42;
print "var: $var\n";

The second program will throw an error:

Global symbol "$var" requires explicit package name.

$var is not defined, which means local $var; is just a declaration! Before using local to declare a variable, make sure that it is defined as a global variable previously.

But why this won't fail?

use strict;
use warnings;

local $a = 42;
print "var: $a\n";

The output is: var: 42 .

That's because $a , as well as $b , is a global variable pre-defined in Perl. Remember the sort function?

2. lexical or global?

I was a C programmer before starting using Perl, so the concept of lexical and global variables seems straightforward to me: just corresponds to auto and external variables in C. But there're small differences:

In C, an external variable is a variable defined outside any function block. On the other hand, an automatic variable is a variable defined inside a function block. Like this:

int global;

int main(void) {
    int local;
}

While in Perl, things are subtle:

sub main {
    $var = 42;
}

&main;

print "var: $var\n";

The output is var: 42 , $var is a global variable even it's defined in a function block! Actually in Perl, any variable is declared as global by default.

The lesson is to always add use strict; use warnings; at the beginning of a Perl program, which will force the programmer to declare the lexical variable explicitly, so that we don't get messed up by some mistakes taken for granted.

Ólafur Waage ,May 10, 2009 at 10:25

The perldoc has a good definition of our.

Unlike my, which both allocates storage for a variable and associates a simple name with that storage for use within the current scope, our associates a simple name with a package variable in the current package, for use within the current scope. In other words, our has the same scoping rules as my, but does not necessarily create a variable.

Cosmicnet ,Nov 22, 2014 at 13:57

This is only somewhat related to the question, but I've just discovered a (to me) obscure bit of perl syntax that you can use with "our" (package) variables that you can't use with "my" (local) variables.
#!/usr/bin/perl

our $foo = "BAR";

print $foo . "\n";
${"foo"} = "BAZ";
print $foo . "\n";

Output:

BAR
BAZ

This won't work if you change 'our' to 'my'.

Okuma.Scott ,Sep 6, 2014 at 20:13

print "package is: " . __PACKAGE__ . "\n";
our $test = 1;
print "trying to print global var from main package: $test\n";

package Changed;

{
        my $test = 10;
        my $test1 = 11;
        print "trying to print local vars from a closed block: $test, $test1\n";
}

&Check_global;

sub Check_global {
        print "trying to print global var from a function: $test\n";
}
print "package is: " . __PACKAGE__ . "\n";
print "trying to print global var outside the func and from \"Changed\" package:     $test\n";
print "trying to print local var outside the block $test1\n";

Will Output this:

package is: main
trying to print global var from main package: 1
trying to print local vars from a closed block: 10, 11
trying to print global var from a function: 1
package is: Changed
trying to print global var outside the func and from "Changed" package: 1
trying to print local var outside the block

In case using "use strict" will get this failure while attempting to run the script:

Global symbol "$test1" requires explicit package name at ./check_global.pl line 24.
Execution of ./check_global.pl aborted due to compilation errors.

Nathan Fellman ,Nov 5, 2015 at 14:03

Just try to use the following program :
#!/usr/local/bin/perl
use feature ':5.10';
#use warnings;
package a;
{
my $b = 100;
our $a = 10;


print "$a \n";
print "$b \n";
}

package b;

#my $b = 200;
#our $a = 20 ;

print "in package b value of  my b $a::b \n";
print "in package b value of our a  $a::a \n";

Nathan Fellman ,May 16, 2013 at 11:07

#!/usr/bin/perl -l

use strict;

# if string below commented out, prints 'lol' , if the string enabled, prints 'eeeeeeeee'
#my $lol = 'eeeeeeeeeee' ;
# no errors or warnings at any case, despite of 'strict'

our $lol = eval {$lol} || 'lol' ;

print $lol;

Evgeniy ,Jan 27, 2016 at 4:57

Let us think what an interpreter actually is: it's a piece of code that stores values in memory and lets the instructions in a program that it interprets access those values by their names, which are specified inside these instructions. So, the big job of an interpreter is to shape the rules of how we should use the names in those instructions to access the values that the interpreter stores.

On encountering "my", the interpreter creates a lexical variable: a named value that the interpreter can access only while it executes a block, and only from within that syntactic block. On encountering "our", the interpreter makes a lexical alias of a package variable: it binds a name, which the interpreter is supposed from then on to process as a lexical variable's name, until the block is finished, to the value of the package variable with the same name.

The effect is that you can then pretend that you're using a lexical variable and bypass the rules of 'use strict' on full qualification of package variables. Since the interpreter automatically creates package variables when they are first used, the side effect of using "our" may also be that the interpreter creates a package variable as well. In this case, two things are created: a package variable, which the interpreter can access from everywhere, provided it's properly designated as requested by 'use strict' (prepended with the name of its package and two colons), and its lexical alias.

Sources:

Recommended Links

Google matched content

Softpanorama Recommended

Top articles

Sites

'our' is not 'my'



Etc

Society

Groupthink : Two Party System as Polyarchy : Corruption of Regulators : Bureaucracies : Understanding Micromanagers and Control Freaks : Toxic Managers :   Harvard Mafia : Diplomatic Communication : Surviving a Bad Performance Review : Insufficient Retirement Funds as Immanent Problem of Neoliberal Regime : PseudoScience : Who Rules America : Neoliberalism  : The Iron Law of Oligarchy : Libertarian Philosophy

Quotes

War and Peace : Skeptical Finance : John Kenneth Galbraith :Talleyrand : Oscar Wilde : Otto Von Bismarck : Keynes : George Carlin : Skeptics : Propaganda  : SE quotes : Language Design and Programming Quotes : Random IT-related quotesSomerset Maugham : Marcus Aurelius : Kurt Vonnegut : Eric Hoffer : Winston Churchill : Napoleon Bonaparte : Ambrose BierceBernard Shaw : Mark Twain Quotes

Bulletin:

Vol 25, No.12 (December, 2013) Rational Fools vs. Efficient Crooks The efficient markets hypothesis : Political Skeptic Bulletin, 2013 : Unemployment Bulletin, 2010 :  Vol 23, No.10 (October, 2011) An observation about corporate security departments : Slightly Skeptical Euromaydan Chronicles, June 2014 : Greenspan legacy bulletin, 2008 : Vol 25, No.10 (October, 2013) Cryptolocker Trojan (Win32/Crilock.A) : Vol 25, No.08 (August, 2013) Cloud providers as intelligence collection hubs : Financial Humor Bulletin, 2010 : Inequality Bulletin, 2009 : Financial Humor Bulletin, 2008 : Copyleft Problems Bulletin, 2004 : Financial Humor Bulletin, 2011 : Energy Bulletin, 2010 : Malware Protection Bulletin, 2010 : Vol 26, No.1 (January, 2013) Object-Oriented Cult : Political Skeptic Bulletin, 2011 : Vol 23, No.11 (November, 2011) Softpanorama classification of sysadmin horror stories : Vol 25, No.05 (May, 2013) Corporate bullshit as a communication method  : Vol 25, No.06 (June, 2013) A Note on the Relationship of Brooks Law and Conway Law

History:

Fifty glorious years (1950-2000): the triumph of the US computer engineering : Donald Knuth : TAoCP and its Influence of Computer Science : Richard Stallman : Linus Torvalds  : Larry Wall  : John K. Ousterhout : CTSS : Multix OS Unix History : Unix shell history : VI editor : History of pipes concept : Solaris : MS DOSProgramming Languages History : PL/1 : Simula 67 : C : History of GCC developmentScripting Languages : Perl history   : OS History : Mail : DNS : SSH : CPU Instruction Sets : SPARC systems 1987-2006 : Norton Commander : Norton Utilities : Norton Ghost : Frontpage history : Malware Defense History : GNU Screen : OSS early history

Classic books:

The Peter Principle : Parkinson Law : 1984 : The Mythical Man-MonthHow to Solve It by George Polya : The Art of Computer Programming : The Elements of Programming Style : The Unix Hater’s Handbook : The Jargon file : The True Believer : Programming Pearls : The Good Soldier Svejk : The Power Elite

Most popular humor pages:

Manifest of the Softpanorama IT Slacker Society : Ten Commandments of the IT Slackers Society : Computer Humor Collection : BSD Logo Story : The Cuckoo's Egg : IT Slang : C++ Humor : ARE YOU A BBS ADDICT? : The Perl Purity Test : Object oriented programmers of all nations : Financial Humor : Financial Humor Bulletin, 2008 : Financial Humor Bulletin, 2010 : The Most Comprehensive Collection of Editor-related Humor : Programming Language Humor : Goldman Sachs related humor : Greenspan humor : C Humor : Scripting Humor : Real Programmers Humor : Web Humor : GPL-related Humor : OFM Humor : Politically Incorrect Humor : IDS Humor : "Linux Sucks" Humor : Russian Musical Humor : Best Russian Programmer Humor : Microsoft plans to buy Catholic Church : Richard Stallman Related Humor : Admin Humor : Perl-related Humor : Linus Torvalds Related humor : PseudoScience Related Humor : Networking Humor : Shell Humor : Financial Humor Bulletin, 2011 : Financial Humor Bulletin, 2012 : Financial Humor Bulletin, 2013 : Java Humor : Software Engineering Humor : Sun Solaris Related Humor : Education Humor : IBM Humor : Assembler-related Humor : VIM Humor : Computer Viruses Humor : Bright tomorrow is rescheduled to a day after tomorrow : Classic Computer Humor

The Last but not Least Technology is dominated by two types of people: those who understand what they do not manage and those who manage what they do not understand ~Archibald Putt. Ph.D


Copyright © 1996-2021 by Softpanorama Society. www.softpanorama.org was initially created as a service to the (now defunct) UN Sustainable Development Networking Programme (SDNP) without any remuneration. This document is an industrial compilation designed and created exclusively for educational use and is distributed under the Softpanorama Content License. Original materials copyright belong to respective owners. Quotes are made for educational purposes only in compliance with the fair use doctrine.

FAIR USE NOTICE This site contains copyrighted material the use of which has not always been specifically authorized by the copyright owner. We are making such material available to advance understanding of computer science, IT technology, economic, scientific, and social issues. We believe this constitutes a 'fair use' of any such copyrighted material as provided by section 107 of the US Copyright Law according to which such material can be distributed without profit exclusively for research and educational purposes.

This is a Spartan WHYFF (We Help You For Free) site written by people for whom English is not a native language. Grammar and spelling errors should be expected. The site contain some broken links as it develops like a living tree...

You can use PayPal to to buy a cup of coffee for authors of this site

Disclaimer:

The statements, views and opinions presented on this web page are those of the author (or referenced source) and are not endorsed by, nor do they necessarily reflect, the opinions of the Softpanorama society. We do not warrant the correctness of the information provided or its fitness for any purpose. The site uses AdSense so you need to be aware of Google privacy policy. You you do not want to be tracked by Google please disable Javascript for this site. This site is perfectly usable without Javascript.

Last modified: September, 07, 2020