some puzzles

Michael Fowler michael at shoebox.net
Wed Mar 21 12:01:58 CST 2001


On Tue, Mar 20, 2001 at 05:41:30PM -0800, Rick J wrote:
> my $count = 0;
> callsub();
> while ($count++ < 3)
> {
> 	my $num = 10;
> 	callsub();
> 	sub callsub {
> 		print ++$num, "\n";
> 	}
> 	print "$num\n";
> }
> It prints out 1 11 11 12 10 13 10

[snip]

> Is it due to the elfish closure again?

Yes.  callsub() encapsulates one $num, but your while loop is creating more,
different, $num's.  If you change your code to something like:

    my $count = 0;
    callsub();
    while ($count++ < 3)
    {
        my $num = 10;
        callsub();
        sub callsub {
            $num++;
            print "callsub:   ", \$num, "\n";
        }
        print "while loop: ", \$num, "\n";
    }

This outputs something along the lines of:
    callsub:    SCALAR(0x400290ac)
    callsub:    SCALAR(0x400290ac)
    while loop: SCALAR(0x400290ac)
    callsub:    SCALAR(0x400290ac)
    while loop: SCALAR(0x4001a160)  <-- address of $num changes
    callsub:    SCALAR(0x400290ac)
    while loop: SCALAR(0x4001a160)

Notice when the address in the while loop changes, on the second iteration. 
This is because the my $num has created a second, seperate lexical, that
callsub() doesn't know about; callsub is still modifying the first.

Also notice on the third iteration, the address hasn't changed from the
second.  This is because the address is being reused.  Assigning a reference
to $num to some outside variable will bear this out, but is left as an
exercise to the reader.  :)


Michael
--
Administrator                      www.shoebox.net
Programmer, System Administrator   www.gallanttech.com
--
=================================================
Mailing list info:  If at any time you wish to (un|re)subscribe to
the list send the request to majordomo at hfb.pm.org.  All requests
should be in the body, and look like such
                  subscribe anchorage-pm-list
                  unsubscribe anchorage-pm-list



More information about the Anchorage-pm mailing list