Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris
 
PerlMonks  

Re: understanding closures

by Limbic~Region (Chancellor)
on Sep 23, 2005 at 12:35 UTC ( [id://494501]=note: print w/replies, xml ) Need Help??


in reply to understanding closures

reasonablekeith,
You may want to have a look at Help with the concept of closures. and Closure on Closures. A closure is basically a piece of code that can be executed outside of the scope it was defined, but can still remembers things from that scope. I know you were asking specific questions but I feel those two links will help give you a broader and deeper understanding of the concept.

Cheers - L~R

Replies are listed 'Best First'.
Re^2: understanding closures
by reasonablekeith (Deacon) on Sep 23, 2005 at 13:40 UTC
    Brilliant, Closure on Closures did it for me. The summing up in particular...

    a closure is a subroutine which wraps around lexical variables that it references from the surrounding lexical scope which subsequently means that the lexical variables that are referenced are not garbage collected when their immediate scope is exited

    This story has a sad end, however. To test my knowledge new-found knowledge, I wrote the following.

    sub make_two_counters { my $count = 0; return sub{ $count++ }, sub{ $count+=10 } } my ($counter_plus_one, $counter_plus_ten) = make_two_counters(); print $counter_plus_one->() . "\n"; print $counter_plus_one->() . "\n"; print $counter_plus_ten->() . "\n"; print $counter_plus_one->() . "\n"; print $counter_plus_one->() . "\n"; __OUTPUT__ 0 1 12 12 13
    I was expecting this to print 0,1,11,12,13 - on the grounds that my two anonymous subs would be saving the same reference to the lexical ($count). But it seems to have merged two of my adds in together!! Help.

    BTW: Thanks for all the replies ++

    ---
    my name's not Keith, and I'm not reasonable.
      reasonablekeith,
      Here is a clue - what happens when you forget about closures and run the following code?
      #!/usr/bin/perl use strict; use warnings; my $cnt = 0; print $cnt++, "\n"; print $cnt++, "\n"; print $cnt += 10, "\n"; print $cnt++, "\n"; print $cnt++, "\n";
      The ++ operator (see perlop) first retrieves the current value and then increments the value when used as post-increment.
      • Start at 0
      • Return 0, make $cnt 1
      • Return 1, make $cnt 2
      • Return 2 + 10, make $cnt 12
      • Return 12, make $cnt 13
      • Return 13, make $cnt 14

      Cheers - L~R

      I was expecting this to print 0,1,11,12,13 - on the grounds that my two anonymous subs would be saving the same reference to the lexical ($count). But it seems to have merged two of my adds in together!! Help.

      Your closures are correct. However, you're confused about something else. $count++ will return the value of $count, then add 1 to it. $count+=10 will add 10 to count, then return the value of $count.

      Try the following:

      my $count = 0; sub make_two_counters { return sub{ $count++ }, sub{ $count+=10 } } my ($counter_plus_one, $counter_plus_ten) = make_two_counters(); print $counter_plus_one->() . " ($count)\n"; print $counter_plus_one->() . " ($count)\n"; print $counter_plus_ten->() . " ($count)\n"; print $counter_plus_one->() . " ($count)\n"; print $counter_plus_one->() . " ($count)\n"; __OUTPUT__ 0 (1) 1 (2) 12 (12) 12 (13) 13 (14)

      Does that help?


      My criteria for good software:
      1. Does it work?
      2. Can someone else come in, make a change, and be reasonably certain no bugs were introduced?
      They are sharing the same lexical. What confuses you is the fact that you are doing post-increment. The result of $count++ is the old value of $count. Change that line to ++$count, and try again.
        Yup, you're right. I was too busy wondering about closures to spot that one. Not that this is an excuse. :(

        Thanks everyone.

        ---
        my name's not Keith, and I'm not reasonable.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others chilling in the Monastery: (5)
As of 2024-03-28 13:03 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found