XP is just a number | |
PerlMonks |
comment on |
( [id://3333]=superdoc: print w/replies, xml ) | Need Help?? |
Quick and dirty closure example:
This is a subroutine that returns a new anonymous subroutine. That new subroutine references a lexical variable in an enclosing block. Now: when the subroutine exits, normally there'd be no more references to that variable, so it would disappear. But since the newly-returned subroutine has a reference to it (remember, you're allowed to see lexicals in a scope that encloses you), the new subroutine can still use the variable, even though no other code can directly address it (yeah, we can use cpan:Padwalker or something similar, but that's not really germane to the discussion). Anyway. We've now got this new subroutine; it's called a closure because the block that is the subroutine can reference this otherwise-invisible variable - sometimes you hear it said that the sub has closed over the lexical variable. and we get Notice that each closure preserves its own copy of the closed-over variable. So big deal. Hidden variable. So what? The big deal is twofold: one, the variable is completely controlled by the closure now and its state is carried along with the closure. So You can only look at the variable via the closure's interface. Second, and this is the really useful part, calling the counter sub again with a new starting value manufactures a completely new and separate closure! So you can create as many counters as you like; they all use the same code, but each one tracks its own internal state. One of the really useful things to use this for is being able to "half-call" a subroutine (Technically, I think this is an example of currying, but let's use "half-call" for the sake of explanation.) Let's say you had a subroutine that you knew some of the information you'd need to call it at one point, but wouldn't know the rest of the information until later. One way to do this is to build a hash, store the data, run until you have the rest, then call the sub after looking up the appropriate data. Not too complicated, but it does clutter the flow a bit. We could instead build a closure at the point we have the first set of data: We've done the first part of the call: setting up one or more closures with the information we know now and sticking them in the queue of stuff to finish later. When we get the rest of the data we need, we just pull the closures off one by one and call them with the rest of the data. And we've finished off all the stuff we had queued up to do once we knew the last piece of data. There are loads more ways to use closures; this is just to point you in the direction of thinking "I can make a sub that remembers things. What can I do with that? Do I need it for this problem?" Have the appropriate amount of fun. In reply to Re: Closures Explained
by pemungkah
|
|