Come for the quick hacks, stay for the epiphanies. | |
PerlMonks |
comment on |
( [id://3333]=superdoc: print w/replies, xml ) | Need Help?? |
That's exactly what makes it a closure. Lexical variables live in their own symbol tables (that's not what they're called in Perl 5, but it's the concept: just a mapping of a name to the data structure that represents the appropriate variable container). They nest — that's why you can write code like this:
If you dump the optree with something like B::Concise, you'll see enter, leave, and pad operations. The enter and leave ops govern which symbol table (scratch pad or lexical pad, in Perl 5 terms) is active. Think of it like a stack and you'll get it. The pad operations look up a symbol in the scratch pad. Subroutines (anonymous and named) are represented by data structures called CVs (basically, Code Values). Every CV is attached to a lexical symbol table. That's just a place to store the lexical variables declared and used within that subroutine. To handle the nesting issue, there has to be a way to look outward from inner scopes. If there's no $foo in the tightest, most innermost scope, look outward, one scope at a time, to find the nearest appropriate $foo. (This is complicated a little bit by global variables, which are handled with a different symbol table implementation in Perl 5. There also appears to be variable analysis because of the pad ops, not glob ops. Insert handwaving here; I really don't want to read that code right now.) The code example you're asking about is a closure so that nested variable scopes will work. Or, put the way it actually happened, because nested variable scopes had to work, closures were possible. In reply to Lexicals, Pads, and Closures
by chromatic
|
|