Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw
 
PerlMonks  

comment on

( [id://3333]=superdoc: print w/replies, xml ) Need Help??

Since I'm waiting for my laptop to finish reformatting so I can re-install Mac OS X 10.2.2 (again) I'm going to get picky - hopefully it will come out as constructive criticism (it's meant that way... honest :-)


In the above code $foo can only be seen between the opening and closing braces. This is because they delimit the length of the lexical scope, and after the ending brace that particular instance of $foo no longer exists.

From this description and the examples it might not be clear that $foo is in scope from its declaration to the end of the enclosing block or file - rather than from the first brace. For example:

my $foo = "hello"; { # this affects the outer $foo $foo .= " world"; my $foo = "something else"; print "inner foo is $foo\n"; }; print "outer foo is $foo\n"; # produces inner foo is something else outer foo is hello world

So a lexical scope is a section of code where things can live temporarily. I say they live temporarily because anything created within a lexical scope will be deleted once the scope has been exited ... There is an exception to this rule however ...

I think that the point Elian makes about destruction is still valid. The lifetime of an item is a separate issue to its scope (lexical or otherwise).

A novice could read your description and thing garbage collection only applied to lexically scoped variables, when it is equally true of dynamically scoped variables (in the fact that an item will not be destroyed if a dynamically scoped variable refers to it).

The connection between a variable falling out of scope and it being destroyed will become even more tenuous when we get a proper GC in perl6. Once you have, for example, mark and sweep GC the item can be destroyed some time after it falls out of scope.

When talking about this sort of thing to novices I find it helps to keep variables and the things they label as separate concepts. In:

There is an exception to this rule however - if something is still referring to something created within a lexical scope upon exit of the scope, that thing will not be deleted since it is still being referred to by something. This does not mean you can still refer to it directly, it just means that perl has yet to clean it up.

what is "it"? The first "it" would seem to be talking about the variable, the second the item it identifies. Combining the two can be very confusing.

Variable scope (dynamic or lexical) is only tangentially related to whether the item the variable referred to will be destroyed at the end of the block or not.

The analogy I always use when explaining variables and scoping is luggage labels (the old fashioned kind - a bit of cardboard attached to a piece of string) and suitcases.

The label is the variable. It's attached to the luggage (scalar, hash, or whatever) and can be used to identify it.

You can have more than one label attached to each bit of luggage (when multiple variables identify the same scalar, hash, or whatever).

Variable scoping is about adding and removing labels - it doesn't affect the luggage.

The garbage collector will throw away any luggage without any labels (I'm sure I could get some joke in here about airports if I tried hard enough)

(yes, the analogy falls down when you start talking about references and compound objects, but I'm sure you get the idea :-)


So once our scopes and variables have been set they cannot be changed at runtime, like package globals can.

Might be more clearer to say that lexical scope is defined by the structure of the code at compile time, while dynamic scope is defined by the runtime environment.


What this means is that lexical variables are declared at compile-time, not initialised

Another way you can demonstrate this nicely is with a BEGIN block.

my $foo = "defined"; BEGIN { print "foo is ", defined($foo) ? $foo : 'undef', " during BEGIN ph +ase\n"; }; print "foo is ", defined($foo) ? $foo : undef, " at runtime\n"; # produces foo is undef during BEGIN phase foo is defined at runtime

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. So local is localising a package globals value for the length of a given lexical scope

Not entirely sure that this is quite clear enough - especially the phrase "length of a given lexical scope". We need to define what "length" means in this context :-)

Maybe something like:

" When a package variable is dynamically scoped with local it's current value is saved, and then restored once the block containing the local is exited. "

Hmmm... that's not very clear either... <sigh>... :-)


You might also see examples of it being used to create private variables - this is rather misguided as it is auto-vivifying (creating it upon request of its existence) the variable

Might be worth mentioning the historical context (some of us can remember the perl4 days when we didn't have lexical variables and using local was your only option ;-)


Thirdly, at the exit of a lexical scope all the variables are destroyed (except of course, for those that are still in use), which means your memory won't keep growing and growing as more variables are created.

This is, of course, equally true of dynamic scoped variables... which is why destruction is really a separate issue :-).

Anyway... time to go back to those install CDs... Hope this makes sense. If not, blame my annoyance with hard disk failures.


Update 2002/12/09: The first part of "Re: typeglobs and filehandles" has some relevant content.


In reply to Re: Lexical scoping like a fox by adrianh
in thread Lexical scoping like a fox by broquaint

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or How to display code and escape characters are good places to start.
Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others goofing around in the Monastery: (4)
As of 2024-03-29 12:01 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found