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

Re: What is it I don't understand about perl scoping?

by mattford63 (Sexton)
on Jul 09, 2009 at 21:00 UTC ( [id://778698]=note: print w/replies, xml ) Need Help??


in reply to What is it I don't understand about perl scoping?

This is as much for my own understanding and may not be entirely correct for Perl (I hope so though).

The function &foo has "free variables" (e.g., variables used within the function body that are NOT declared within the function body). This means that Perl has to go outside the scope of the function to try and provide values for them.

The first place it tries is the scope at which the function was called. Update: that's actually not true. It first tries the scope above the function definition, and then the scope above that it until it finds a declaration or stops at the global scope. In the original code it just so happens the scope at which it finds the declarations is the same as where the function is called - see the supplemental example. Now, you might think that as you declare $foo in front of the function call it should have a value of 1 (it is in the same scope after all). However within the same scope of the first $foo declaration there is a second $foo declaration. The second declaration effectively "masks" the first. Perl doesn't like having two declarations in the same scope so chooses the last one it finds as the one to use. And as this happens to be after the function call, the values aren't initialised when &foo is called.

I'm not sure what actually happens behind the scenes i.e. what does "mask" really mean. Does the second declaration actually overwrite the first? Or is the second declaration always found and used before the first?

What's the truth monks?

Supplemental Example

#!/usr/bin/perl use strict; use warnings; my ($foo, $berries) = (89,90); foo(); { my $foo = 89; sub foo { print "$foo, $berries\n"; }; };

Results in:

,90

When sub foo is compiled it can't find a declaration for $foo so checks the parent scope. It finds it at the line "my $foo = 89". At this point Perl binds the varible $foo to a memory location but doesn't set it's value i.e., it just does the declaration not the initialisation. Further this binding is stored with the function sub $foo (note: this is a closure - the free variable $foo in sub foo gets bound (or closed) in the parent scope and permanently attached to the function).

So, even though in the global context $foo is set before the sub foo call, it doesn't matter because sub foo has it's own binding for $foo which hasn't yet been initialised.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://778698]
help
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-04-20 01:59 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found