Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"
 
PerlMonks  

Re: Lexical scoping like a fox

by larsen (Parson)
on Mar 13, 2003 at 21:04 UTC ( #242833=note: print w/ replies, xml ) Need Help??


in reply to Lexical scoping like a fox

++

There's a point where I have problems, thought:
With that said, what local does do is change the value of an existing package global for the length of a given dynamic scope. A dynamic scope is just like a lexical scope but is defined by the length of scope, not the visibility of the scope.
I dropped your italics, and added <strong> to stress the part I can't understand. Could you rephrase it?


Comment on Re: Lexical scoping like a fox
Download Code
Re: Re: Lexical scoping like a fox
by broquaint (Abbot) on Mar 14, 2003 at 10:49 UTC
    There's a point where I have problems, thought
    Sorry, it is a rather tricky to get into words, but hopefully this code will illustrate the difference between then the length and the visibility of a scope
    sub foo { ## start of visible scope ## $x a lexical var only accessable in the *visible* scope my $x = "a lexical var"; ## $y changed for the *length* of the scope local $y = "a dynamic var"; print "foo(\$x): $x\n"; print "foo(\$y): $y\n"; bar($y); } ## end of visible scope sub bar { ## $x is undefined as it is being referenced outside the ## *visible* scope of foo() ## $y is still changed as the scope of foo() has not ## *exitted* yet print "bar(\$x): $x\n"; print "bar(\$y): $y\n"; } $y = "a global var"; foo(); ## now foo() has exitted $y reverts to it's original value print "main(\$y): $y\n"; __output__ foo($x): a lexical var foo($y): a dynamic var bar($x): bar($y): a dynamic var main($y): a global var

    HTH

    _________
    broquaint

Re: Re: Lexical scoping like a fox
by hv (Parson) on Mar 14, 2003 at 13:43 UTC

    Maybe it would be easier to express the distinction as spatial versus temporal scoping, which is an approach that I think makes sense at least until you start throwing threads and processes into the mix.

    Let's take this example:

    print "Just before start of scope\n"; { print "Just after start of scope\n"; my $a = 1; local $b = 1; print "a=$a, b=$b\n"; foo(); print "Just before end of scope\n"; } print "Just after end of scope\n";

    Now, in this example, the line 'my $a = 1;' introduces a lexical variable. Any reference to $a in the statements following that introduction until the end of the scope refer to this newly introduced variable - and only those lines. This is a spatial scope: if the foo subroutine refers to a $a variable, it won't see this $a, because foo is not defined within this scope.

    The line 'local $b = 1;' introduces a localisation - it tells the interpreter to save the current copy of the (package) variable $b, to be restored when execution reaches the end of the scope. Now it is a matter of time: after this localisation has been executed, anyone that looks at this package variable $b before the end of this scope is reached will see the localised version. If the foo subroutine refers to the package variable $b, it will see the localised version (for this call, at least).

    Does that help at all?

    Hugo
      Excellent tutorial for me(newbie)
      and yes Hugo, your example made it clear for me as I wrote out your example
      use strict; sub foo { print "\$a is ", defined($a) ? $a : 'undef', $/; print "\$b is ", defined($b) ? $b : 'undef', $/; } print "Just before start of scope\n"; { print "Just after start of scope\n"; my $a = 1; local $b = 1; print "a=$a, b=$b\n"; foo(); print "Just before end of scope\n"; } print "Just after end of scope\n"; print "\$a is ", defined($a) ? $a : 'undef', $/; print "\$b is ", defined($b) ? $b : 'undef', $/;
      Couple other questions/comments
      1)using input record separator as newline indicator is very interesting. Never seen it before but works well. Any reason?
      I am assuming it's just a style issue?
      2)Below code from tutorial does not work when I insert my next to variable.. can someone explain this?
      [root@myserver tmp]# cat -n !$ cat -n ./per_begin.pl1 1 #!/usr/bin/perl -w 2 3 use strict; 4 5 6 my $x = "original state"; 7 8 sub foo { 9 print " \$x is: $x\n"; 10 } 11 12 { # beginning of lexical scope 13 14 local $x = "altered state"; 15 foo(); 16 17 } # end of lexical scope 18 print "\$x is: $x\n"; [root@myserver tmp]# ./!$ ././per_begin.pl1 Can't localize lexical variable $x at ././per_begin.pl1 line 14.
      3)can someone explain further on "lexical variables are declared at compile-time, not initialised?
      Is this because BEGIN runs during compile-time? I sneaked in a new my $foo = something inside of BEGIN
      block and execution of the code came out w/ foo is something during BEGIN phase
        3)can someone explain further on "lexical variables are declared at compile-time, not initialised?

        It's the difference between "existing but having an undefined value (what you get when a variable is declared but not initialized -- ie. defined($var) returns false) vs. "existing with a defined value (what you get when you declare and initialize).

        1)using input record separator as newline indicator is very interesting. Never seen it before but works well. Any reason? I am assuming it's just a style issue?

        I guess it's more along "a \n is a \n is a \n" - $/ is a global, and that could be changed far away without you knowing it; so it's more safety than style.

        2)Below code from tutorial does not work when I insert my next to variable.. can someone explain this?

        You are allocating a lexical $x, not a package global (which would be either use vars '$x' or our $x), and local aliases only package globals. You can't (shouldn't) allocate globs and lexicals of the same name in the same scope:

        our $x; my $x; # gives a warning
        our $x; { my $x; # ok }
        3)can someone explain further on "lexical variables are declared at compile-time, not initialised? Is this because BEGIN runs during compile-time? I sneaked in a new my $foo = something inside of BEGIN block and execution of the code came out w/ foo is something during BEGIN phase

        "lexical variables are declared at compile-time, not initialised" means "the container is created, but nothing is put into it". The initialization (= puting something into the bucket) happens at run time. BEGIN blocks are compiled and immediately run, that's why "code came out w/ foo is something during BEGIN phase".

        See also my/local, space/time (was: Re: The difference between my and local).

        --shmem

        _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                      /\_¯/(q    /
        ----------------------------  \__(m.====·.(_("always off the crowd"))."·
        ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://242833]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others browsing the Monastery: (11)
As of 2014-09-18 19:20 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    How do you remember the number of days in each month?











    Results (121 votes), past polls