Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

Re: Re: Lexical scoping like a fox

by hv (Parson)
on Mar 14, 2003 at 13:43 UTC ( #243024=note: print w/ replies, xml ) Need Help??


in reply to Re: Lexical scoping like a fox
in thread Lexical scoping like a fox

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


Comment on Re: Re: Lexical scoping like a fox
Select or Download Code
Replies are listed 'Best First'.
Re^3: Lexical scoping like a fox
by convenientstore (Pilgrim) on Jan 13, 2008 at 16:26 UTC
    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
      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}
      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).

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others exploiting the Monastery: (6)
As of 2015-07-28 04:15 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (252 votes), past polls