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

I have taken folloing from a post on this forum. Still I could not make out few things.

use vars qw/$x, @y, %z, $d, @e, %f, $p, @q, %r/; $a = 10; my ($b) ; # what is the meaning of bracket around variable name ? { # ... my ($p, @q, %r); local ($d, @e, %f); # (1) # ... sub foo { # ... } # ... foo(17); # (2) bar($p,29); # (3) lbar($d, 31); # ... } # (4) # ... sub bar { # ... } { # ... local ($x, @y, %z); # (5) local $a = 20; my $a = 30; # ... sub baz { # ... } # ... baz(17); # (6) quux($x,29); # (7) # ... sub child { $b = a * 10; # which value of \$a will be available here ? } } # (8) # ... sub quux { # ... } # ... baz(29); # (9)


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

2) If local variable and my variable both are declared using same name, is that allowed or is that an error ? If global variable and local variable , both have same name and I want to use global variable in the scope where my $a variable is declared, I can call it using $::a. In the child(), I have not declared $a and I want to call global value of $a in the child(). If I again use $::a, will it call the global value of $a or will it be value my $a ? If call $a in the child(), without using $::a, will it still call global value of $a or my $a declared in the scope in which child() is declared ?

3) If thats allowed, and in the sub(), if I am using variable name, which valkue will be taken in sub()

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 () ?

5) Declaring variables at the beginning of the code using "use vars", is it the only way to declare global variables ? or just declaring variables in the beginning of the code without local or my makes them global variables ?

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

7) If my variable is declared to make its scope local, then whats the point in declaring my variable at the top level ? Like the "my ($b)" or my $c in this example ?

8) Is it true that my $p will not be available to bar() , as bar() is defined outside the scope of my ($p, @q, %r) and only global $p will be available ? But local $d will be available to lbar(), as lbar() is called within the in time scope of $d and it will not use global value of $d?

Please excuse me , if some questrions sound like repeated.

Thanks

Replies are listed 'Best First'.
Re: Understanding difference between my and local variables.
by ikegami (Patriarch) on Oct 15, 2010 at 03:07 UTC

    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.

      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.

      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.

Re: Understanding difference between my and local variables.
by jwkrahn (Abbot) on Oct 15, 2010 at 02:44 UTC
Re: Understanding difference between my and local variables.
by JavaFan (Canon) on Oct 15, 2010 at 05:43 UTC
    I don't understand why you are asking questions 1 to 4. Surely it's easier to try out whether it's possible than typing in the question?

    As for 5), the answer is, "it's not really a sensible question". Global variables have to do with scope - a variable is global if it can be accessed from the outer scope. Lexical (my) can, if declared appropriately. Package variables always can (obviously), but they don't need to be declared - from a language point of view, they always exist. "use vars" is just a way of telling Perl "in this scope, I'm going to use these package variables, and I'm not going to refer to them by their full name" (use vars will have some effects in perl - but that's implementation, not language).

    As for 6), there's no difference. But there is a difference between my($x, $y); and my $x, $y;. The former is equivalent to my $x; my $y;, the latter to my $x; $y;.

    I do not understand question 7). Where is my $c?

    8) you can just try out for yourself.

      >perl -E"say scalar( my $x = qw( a b c ) );" c >perl -E"say scalar( my ($x) = qw( a b c ) );" 3
        The question wasn't what the difference is between my ($x) = ..." and my $x = ..... The question was what the difference is between my ($x); and my $x;.
Re: Understanding difference between my and local variables.
by locked_user sundialsvc4 (Abbot) on Oct 15, 2010 at 14:17 UTC

    One point-of-confusion that might help to be cleared up is ... just how Perl uses the concept of namespaces.   The package statement introduces a new namespace, but a single file can have as many package statements within it as you wish.   (It may not be a nifty practice, but it can be done.)   There is a default namespace that is assumed to exist if no other namespace has been put into effect.

    Therefore, everything that you declare is always associated with some namespace.   There is no “global universe outside all the spheres,” at least, not as far as I know.   (But I am a simple monk, not inducted into the Deeper Mysteries.)

      $a = 10; my $b = 20; # Can this be accessed inside the subroutine ? my ($c) = 30; # what is the meaning of bracket around variable name ? { # ... my ($p, @q, %r); local ($d, @e, %f); # (1) $b = 40; # does this change value of my $b ? # ... sub foo { # ... } # ... foo(17); # (2) bar($p,29); # (3) lbar($d, 31); # ... } # (4) # ... sub bar { my $d = 60; $b = 50; # ... }
      Can we access the variable "b" declared as my variable at the beginning of the code, inside the subroutine ? Or is it out of scope ? We can not access my $d, declared inside sub bar(). Likewise, can a my $b variable, which is declared outside the bar() and at the beginning of the code, be accessed inside sub bar() ?

      Thanks