in reply to Understanding difference between my and local variables.

Short version:

local doesn't declare variables. It saves the value of a package variable and makes it so the value gets restored when the lexical scope is exited.


1) Can global variable be declared anywhere in the code or only at the beginning of the code ?

Lexical variables can be declared anywhere an expression can be found.

Package variables need not be declared. use vars can be present anywhere a statement can be found.

our, which creates a lexical alias to a package var, can be present anywhere an expression can be found.

2) If local variable and my variable both are declared using same name, is that allowed or is that an error ?

local doesn't declare variables. It saves the value of a package variable and makes it so the value gets restored when the lexical scope is exited.

In our vs my, the latter wins IIRC. Easy to test.

4) If a sub() is declared within a sub(), can the variables declared in super sub() be accessed in child sub() without being declared in child () ?

If the inner sub is an anonymous sub, yes. Even if the outer sub has exited before the inner sub has exited.

>perl -E"sub mk { my $x=$_[0]; sub { $x } } $x=mk('a'); $y=mk('b'); s +ay $x->(),$y->()" ab

Don't nest named subs. You'll likely end up with buggy code (a warning will be issued if you have them on and the buggy situation arises), and it doesn't serve any purpose (the inner sub isn't public).

5) Declaring variables at the beginning of the code using "use vars", is it the only way to declare global variables ?

use vars and our.

or just declaring variables in the beginning of the code without local or my makes them global variables ?

Global variables are created on the fly whenever they are used.

6) what is the difference between my $b; and my ($b);

The latter is considered a list in order to determine if an assignment operator is a scalar assignment operator or a list assignment operator.

# The "=" is a scalar assignment operator, so: # - f() is evaluated in scalar context. # - The assignment returns $x. my $x = f(); # The "=" is a list assignment operator, so: # - f() is evaluated in list context. # - The assignment returns ($x) in list context, or # - the number of items returned by f() in scalar context. my ($x) = f();

7) If my variable is declared to make its scope local

local doesn't declare variables. local doesn't change the scope of a variable.

Replies are listed 'Best First'.
Re^2: Understanding difference between my and local variables.
by ig (Vicar) on Oct 15, 2010 at 05:42 UTC

    While your short description of local may well be correct, I think a correct understanding of it depends very much on understanding what a value is, and that this can only be correctly understood with an understanding of perl's internal data structures. To someone unfamiliar with the internals, I think it is easily misunderstood.

    To clarify, notice the effect on $x, $y and $$z in the following example:

    $x = 10; *y = *x; $z = \$x; { print "\$x = $x, \$y = $y, \$\$z = $$z \n"; local $x; print "\$x = $x, \$y = $y, \$\$z = $$z \n"; $x = 20; print "\$x = $x, \$y = $y, \$\$z = $$z \n"; }

    Which produces:

    $x = 10, $y = 10, $$z = 10 $x = , $y = , $$z = 10 $x = 20, $y = 20, $$z = 10

    It is easy to interpret your description to mean that $$z would change as local $x changed. Yet it doesn't.

    The re-initialization of $x and $y may also be a bit of a surprise, even to someone who read Temporary Values via local(). This is subtly hinted at by A "local" just gives temporary values to global (meaning package) variables., but I find that It does not create a local variable. is particularly prone to mislead. In this case, whether the statement is correctly understood or not depends on the understanding of variable which, again, can only be correctly understood with an understanding of perl's internal data structures.

    update: Rereading Temporary Values via local() is see: As for simple variables, this creates new, dynamically scoped values.. So, it doesn't create new variables but it does create new values. This may make the initialization of the local'ized variables less surprising.

    Compare this with explicitly saving and restoring the variable, as your description of local suggests:

    $x = 10; *y = *x; $z = \$x; { print "\$x = $x, \$y = $y, \$\$z = $$z \n"; $savex = $x; print "\$x = $x, \$y = $y, \$\$z = $$z \n"; $x = 20; print "\$x = $x, \$y = $y, \$\$z = $$z \n"; $x = $savex; }

    Which produces:

    $x = 10, $y = 10, $$z = 10 $x = 10, $y = 10, $$z = 10 $x = 20, $y = 20, $$z = 20

    This also occurs with the implicit localization of the foreach loop.

    $x = 10; *y = *x; $z = \$x; foreach $x (1..3) { print "\$x = $x, \$y = $y, \$\$z = $$z \n"; }

    produces:

    $x = 1, $y = 1, $$z = 10 $x = 2, $y = 2, $$z = 10 $x = 3, $y = 3, $$z = 10

    This is not necessarily inconsistent with your description, but it may be surprising to some, so I thought worth pointing it out to others. There is more on this elsewhere, including Difference b/w my and local var?

      "Variable" and "value" are not particular well defined terms; there are many layers, and they can't be separated into variable and value. Statements that rely on strong definitions like "it doesn't create new variables but it does create new values" convey no meaningful info and lead to frustration. It's best to avoid them.

      In any case, how the values are saved is far beyond what the OP needed to know now. Or ever, even.

Re^2: Understanding difference between my and local variables.
by manishrathi (Beadle) on Oct 15, 2010 at 05:41 UTC
    That removes lot of confusion. Still some questions. Let me get this terms understood

    When You say Package variable, then you mean global variable. So global and package variable are one and same, correct ? What if, I declare a package variable and that variable does not exist in the package. Will that variable be created in the package ?

    If a variable is declared without "my" prefix, thats a global variable or package variable, right ? If a variable is declared with "my" prefix, then its lexical variable, right ?

    If a variable is not declared as global variable (package variable) say $x, then can we still use this variable $x as local variable ? Or variable has to be declared as global variable in order to assign it local scope ?
      So global and package variable are one and same, correct ?
      No. Global just means it can be accessed globally. Lexical variables may be global. If your program is just one file, and my declare "my $foo;" at the top of the file, that variable will be global.

      Depending on what you mean by "global variable" exactly, either all package variables are global (because you always get to their values from anywhere in the program), or they are only global when their name is declared in the other scope (because getting to the value from other scopes requires fully qualified names).

      What if, I declare a package variable and that variable does not exist in the package. Will that variable be created in the package
      That depend on your point of view. Do you want to look at from the language POV? Then the answer is no. Package variables always exist. Implementation wise, however, means that a variable may be created when "declared". use vars and our may create the variable. But the variable may already exist - and the our (or use vars) statement just means the variable is known by a different name during the compilation process.
      If a variable is declared without "my" prefix, thats a global variable or package variable, right
      Right.
      If a variable is not declared as global variable (package variable) say $x, then can we still use this variable $x as local variable
      Yes, but it will be a different one. You cannot localize a lexical variable (but you can localized elements of lexical arrays and hashes, go figure). Such a local statement will introduce a package $x. I strongly advice as such coding practise.

      When You say Package variable, then you mean global variable.

      When you say global, you mean package variable.

      Package variables are global. Loosely speaking, people also call file-scoped lexicals global variables, so you can have global lexical variables too.

      What if, I declare a package variable and that variable does not exist in the package. Will that variable be created in the package ?

      Declaring means to make exist. Your condition is a contradiction (never true).

      If a variable is declared without "my" prefix, thats a global variable or package variable, right

      How are you declaring it?

      use vars qw( $var ); declares a package variable.

      our $var; declares a package variable. (Not exactly, but it's a useful simple way of thinking of it.)

      If a variable is not declared as global variable (package variable), then can we still use this variable $x as local variable ?

      I think you're asking if you can use local can be used on variables other than package variables. Yes.

      • Package variables
      • Array elements
      • Hash elements

      Note that it doesn't matter if the package variable was declared or not.