From pisium at yahoo.com Tue Mar 20 13:40:58 2001 From: pisium at yahoo.com (Rick J) Date: Wed Aug 4 23:56:49 2004 Subject: some puzzles Message-ID: <20010320194058.43161.qmail@web13307.mail.yahoo.com> Hi, Michael, Thanks for the explanation on scoping, and great site http://perl.plover.com. I have read most of articles. I have a question about my scope as follow. use strict; my $count = 0; callsub() while ($count++ < 3); { my $num = 10; sub callsub { print ++$num, "\t"; } print "$num\n"; } It prints out 1 2 3 10. Is my understanding right? The first time when callsub() was called, the callsub was in the outer block where my $num was defined. So local $num was declared and defined, however, the process didn't reach the statement 'my $num = 10', so it did not get the defined value and printed as 1 2 3 respectively instead of 11 12 13. However, after the while loop was done, and this time, the program pass that statement, and got the value and printed it as 10. I am still wondering why in the sub, it did not print 11 12 13. My here, looks more like local, because in that block, it stores 2 values for the my $num, one is 10, and the other is 1, 2, or 3. I am so clear and sure. Another question is about assignment. I know that in assignment, if the right side is array, and left side is list or array, it just assigns the values accordingly. If the left side is scalar, it assigns the total number of elements in that array to the scalar variable. So the following cases indicate: 1. @arr = (10, 20, 30); $var = @arr; #$var is 3 2. $var = (10, 20, 30); #$var is 30 3. my ($v1, $v2, @arr); $v1 = (($v2, @arr) = (10, 20, 30, 40)); #$v1 is 4, $v2 is 10 and @arr has 20 30 40 4. @arr = (10, 20, 30); $var = (@arr); #$var is 3 5. $var = 10, 20, 30; #$var is 10 I don't understand 2 and 4 and 5. 2.and 5. Why the results are different because of the parentheses? Isn't in case 2, the parentheses have to be taken off before the assignment? If that's the case, 2 and 5 should be same. 4. Array in the parentheses, I think, should be flattened out before the assignment? Therefore, $var = (@arr) should be equal to $var = (10, 20, 30). But it seems different. Therefore, the result isn't same between if (@arr) and if (10, 20, 30). Please advise, thanks. Rick __________________________________________________ Do You Yahoo!? Get email at your own domain with Yahoo! Mail. http://personal.mail.yahoo.com/ ================================================= Mailing list info: If at any time you wish to (un|re)subscribe to the list send the request to majordomo@hfb.pm.org. All requests should be in the body, and look like such subscribe anchorage-pm-list unsubscribe anchorage-pm-list From rox at tara-lu.com Tue Mar 20 13:22:15 2001 From: rox at tara-lu.com (Roxanne Reid-Bennett) Date: Wed Aug 4 23:56:49 2004 Subject: some puzzles References: <20010320194058.43161.qmail@web13307.mail.yahoo.com> Message-ID: <3AB7ADE7.406648AC@tara-lu.com> Rick J wrote: [...] > It prints out 1 2 3 10. [...] > I am still wondering why in the sub, it did not print > 11 12 13. I haven't used sub-scoped subroutines much, so I don't have the internals for perl down on that. It seems weird to me that you can even access "callsub" outside the while loop. Based on my understanding (from 30 years ago) of scoping. However, running this through the Activestate debugger, it does in fact run through the callsub 3 times before executing the $num = 10. I haven't played with the perl debugger on either platform (Linux or Winnt) enough to know how to check, but I'll bet dollars to donuts that the $num inside the callsub is the same as the one that is later assigned 10. [evaluating to a memory address would verify - but I'm not going to take the time to figure out how to do that at the moment] > 2. $var = (10, 20, 30); #$var is 30 > 4. @arr = (10, 20, 30); > $var = (@arr); #$var is 3 > 5. $var = 10, 20, 30; #$var is 10 > 2.and 5. Why the results are different because of the > parentheses? The parens turn the right side into an anonymous array. The 10, 20, 30 is a list of values, but not explicitly "arrayed". As a result I would have assumed you would get 3, not 30 on "2.". 5. made sense to me, you got the first value off the list. However this brought up some other cases to me which didn't behave as I expected, so I added a few cases to your example: 6. $var, $v2, $v3 = 10, 20, 30; #$var is 10, $v2 is 10, $v3 is 10 7. $vx1, $vx2, $vx3 = (10, 20, 30); #$vx1 is "" $vx2 is "" $vx3 is 30 8. ($v1, $v2, $v3) = (10, 20, 30); #$v1 is 10 $v2 is 20 $v3 is 30 8. makes sense to me, but 6 and 7 were not what I expected to see. > 4. Array in the parentheses, I think, should be > flattened out before the assignment? Therefore, $var = > (@arr) should be equal to $var = (10, 20, 30). But it > seems different. Therefore, the result isn't same > between if (@arr) and if (10, 20, 30). but is the same as $var = @arr; The (@arr) expands the @arr into the (), then takes the length. The issue seems to resolve around anonymous arrays versus named (?) arrays, even if partially named or not. Michael is more than welcome to respond, this just arroused my curiosity. Rox -- Roxanne Reid-Bennett rox@tara-lu.com President, Tara-Lu Corporation http://www.tara-lu.com/ Quality brings its own reward. ================================================= Mailing list info: If at any time you wish to (un|re)subscribe to the list send the request to majordomo@hfb.pm.org. All requests should be in the body, and look like such subscribe anchorage-pm-list unsubscribe anchorage-pm-list From michael at shoebox.net Tue Mar 20 16:33:50 2001 From: michael at shoebox.net (Michael Fowler) Date: Wed Aug 4 23:56:49 2004 Subject: some puzzles In-Reply-To: <20010320194058.43161.qmail@web13307.mail.yahoo.com>; from pisium@yahoo.com on Tue, Mar 20, 2001 at 11:40:58AM -0800 References: <20010320194058.43161.qmail@web13307.mail.yahoo.com> Message-ID: <20010320133350.A1537@shoebox.net> On Tue, Mar 20, 2001 at 11:40:58AM -0800, Rick J wrote: > Thanks for the explanation on scoping, and great site > http://perl.plover.com. I have read most of articles. > I have a question about my scope as follow. You're most welcome. > use strict; > my $count = 0; > callsub() while ($count++ < 3); > { > my $num = 10; > sub callsub { > print ++$num, "\t"; > } > print "$num\n"; > } > It prints out 1 2 3 10. > > Is my understanding right? The first time when > callsub() was called, the callsub was in the outer > block where my $num was defined. So local $num was > declared and defined, however, the process didn't > reach the statement 'my $num = 10', so it did not get > the defined value and printed as 1 2 3 respectively > instead of 11 12 13. However, after the while loop was > done, and this time, the program pass that statement, > and got the value and printed it as 10. You're dealing with two issues here. One is a closure, the other is confusion about what happens when a subroutine is defined. You should probably find a more robust description of clusures, but briefly a closure is a subroutine that carries a set of lexical variables (defined outside of the subroutine definition, but in the same scope) around with it. The concept can be difficult to grasp; I will try to elaborate with your code. So the first thing you're seeing is the closure, callsub(), in action. callsub() is defined in the same scope as the lexical $num, and it uses $num in the body (of the subroutine), therefore it is a closure around $num. $num has no value initially, because when you first call callsub() here: callsub() while ($count++ < 3); the "$num = 10;" line has not yet been encountered. callsub() increments the lexical $num, which is effectively at 0, to 1. This is why you see the sequence 1, 2, 3. After that code, you enter the block: { my $num = 10; sub callsub { print ++$num, "\t"; } print "$num\n"; } $num is initialized to 10, and subsequently printed out. callsub() may be defined here, but it is not actually called, so no increment takes place. > I am still wondering why in the sub, it did not print > 11 12 13. My here, looks more like local, because in > that block, it stores 2 values for the my $num, one is > 10, and the other is 1, 2, or 3. I am so clear and > sure. If you want to see the sequence 11, 12, 13 you have to initialize $num to 10 before calling callsub(). In your code you haven't done that. What can be confusing is when statements are encountered. Recall I said the initialization of $num wasn't encountered before the first call to callsub(), but it's still a lexical variable. The reason is the my operator has a compile-time effect, whereas assignment is done at runtime. So while $num has been declared lexical, the code initializing it has not yet been encountered by the time callsub() is first called. > Another question is about assignment. I know that in > assignment, if the right side is array, and left side > is list or array, it just assigns the values > accordingly. If the left side is scalar, it assigns > the total number of elements in that array to the > scalar variable. So the following cases indicate: Here you seem to be confusing arrays and lists. An array in scalar context yields the number of elements in the array; a list in scalar context yields the last element of the list. The simple rule of thumb is that an array is prefixed by the @ symbol, a list is not. > 2. $var = (10, 20, 30); #$var is 30 (10, 20, 30) is a list. > 3. my ($v1, $v2, @arr); > $v1 = (($v2, @arr) = (10, 20, 30, 40)); > #$v1 is 4, $v2 is 10 and @arr has 20 30 40 This is a special case. A list assignemnt (that's the "($vw, @arr) =" you're using) in scalar context yields the number of elements on the right side of the assignment, much like an array, but it's still a list. > 4. @arr = (10, 20, 30); > $var = (@arr); #$var is 3 What you're seeing is a list of one element being evaluated in scalar context, yielding the last element, @arr. @arr is then evaluated in scalar context, yielding 3. > 5. $var = 10, 20, 30; #$var is 10 This is simply a list of statements, where "$var = 10", "20", and "30" are the individual statements. You would use such a thing in something like: print("test passed"), $test_failed = 0, next if $test_passed; 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@hfb.pm.org. All requests should be in the body, and look like such subscribe anchorage-pm-list unsubscribe anchorage-pm-list From michael at shoebox.net Tue Mar 20 16:41:11 2001 From: michael at shoebox.net (Michael Fowler) Date: Wed Aug 4 23:56:49 2004 Subject: some puzzles In-Reply-To: <3AB7ADE7.406648AC@tara-lu.com>; from rox@tara-lu.com on Tue, Mar 20, 2001 at 11:22:15AM -0800 References: <20010320194058.43161.qmail@web13307.mail.yahoo.com> <3AB7ADE7.406648AC@tara-lu.com> Message-ID: <20010320134111.B1537@shoebox.net> On Tue, Mar 20, 2001 at 11:22:15AM -0800, Roxanne Reid-Bennett wrote: > I haven't used sub-scoped subroutines much, so I don't have the internals > for perl down on that. It seems weird to me that you can even access > "callsub" outside the while loop. Based on my understanding (from 30 > years ago) of scoping. > > However, running this through the Activestate debugger, it does in fact > run through the callsub 3 times before executing the $num = 10. Perl doesn't have scoped named subroutines, the sub in the block is a bit misleading (and probably part of the source of his confusion). When perl sees a named subroutine declaration the subroutine is available almost anywhere. The only place it wouldn't be available is in code being evaluated before the sub declaration is, such as within a BEGIN block or a use'd module. The closest you can get to a scoped subroutine is by using a lexical scalar and a code reference: { my $sub = sub { ... }; $sub->(...); } $sub->(...); # no scalar named $sub, abort, abort! 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@hfb.pm.org. All requests should be in the body, and look like such subscribe anchorage-pm-list unsubscribe anchorage-pm-list From rox at tara-lu.com Tue Mar 20 15:55:47 2001 From: rox at tara-lu.com (Roxanne Reid-Bennett) Date: Wed Aug 4 23:56:49 2004 Subject: some puzzles References: <20010320194058.43161.qmail@web13307.mail.yahoo.com> <3AB7ADE7.406648AC@tara-lu.com> <20010320134111.B1537@shoebox.net> Message-ID: <3AB7D1E3.EDF1F46@tara-lu.com> Michael Fowler wrote: > > > > However, running this through the Activestate debugger, it does in fact > > run through the callsub 3 times before executing the $num = 10. > > Perl doesn't have scoped named subroutines, the sub in the block is a bit > misleading (and probably part of the source of his confusion). When perl > sees a named subroutine declaration the subroutine is available almost > anywhere. The only place it wouldn't be available is in code being aha, ok. it didn't help that I read the following: > my $count = 0; > callsub() while ($count++ < 3); > { ... > } as (re-arranged a little bit to make my point) > my $count = 0; > callsub(); > while ($count++ < 3) > { ... > } Makes a bit of a difference [and teaches me once again to read the code as the compiler does, not just read what I'm seeing and make allowances for other people's formatting ...] I had also totally forgotten the distinction between arrays and lists. Thanks Michael. Rox -- Roxanne Reid-Bennett rox@tara-lu.com President, Tara-Lu Corporation http://www.tara-lu.com/ Quality brings its own reward. ================================================= Mailing list info: If at any time you wish to (un|re)subscribe to the list send the request to majordomo@hfb.pm.org. All requests should be in the body, and look like such subscribe anchorage-pm-list unsubscribe anchorage-pm-list From michael at shoebox.net Tue Mar 20 17:04:38 2001 From: michael at shoebox.net (Michael Fowler) Date: Wed Aug 4 23:56:49 2004 Subject: some puzzles In-Reply-To: <3AB7ADE7.406648AC@tara-lu.com>; from rox@tara-lu.com on Tue, Mar 20, 2001 at 11:22:15AM -0800 References: <20010320194058.43161.qmail@web13307.mail.yahoo.com> <3AB7ADE7.406648AC@tara-lu.com> Message-ID: <20010320140438.A1639@shoebox.net> On Tue, Mar 20, 2001 at 11:22:15AM -0800, Roxanne Reid-Bennett wrote: I missed these examples, otherwise I would've commented on them in my earlier email. > 6. $var, $v2, $v3 = 10, 20, 30; #$var is 10, $v2 is 10, $v3 is 10 > 7. $vx1, $vx2, $vx3 = (10, 20, 30); #$vx1 is "" $vx2 is "" $vx3 is 30 > 8. ($v1, $v2, $v3) = (10, 20, 30); #$v1 is 10 $v2 is 20 $v3 is 30 > > 8. makes sense to me, but 6 and 7 were not what I expected to see. 6 and 7 don't make sense, and in fact aren't what I see with various versions of Perl. What version of Perl are you using? With 5.00405, 5.00503, and 5.6.0 I see the following: Example 6: > perl -wle '$var, $v2, $v3 = 10, 20, 30; print "$var, $v2, $v3";' Useless use of a variable in void context at -e line 1. Useless use of a variable in void context at -e line 1. Useless use of a constant in void context at -e line 1. Useless use of a constant in void context at -e line 1. Use of uninitialized value at -e line 1. Use of uninitialized value at -e line 1. , , 10 Which is what I expect. $var and $v2 are being discarded, as are 20 and 30; the only operation of substance is $v3 = 10. Example 7: > perl -wle '$vx1, $vx2, $vx3 = (10, 20, 30); print "$vx1, $vx2, $vx3";' Useless use of a constant in void context at -e line 1. Useless use of a constant in void context at -e line 1. Useless use of a variable in void context at -e line 1. Useless use of a variable in void context at -e line 1. Use of uninitialized value at -e line 1. Use of uninitialized value at -e line 1. , , 30 (with minor changes in the warnings for 5.6.0) $vx1 and $vx2 are being discarded, and the list (10, 20, 30) is being evaluated in scalar context, yielding 30 and discarding 10 and 20. 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@hfb.pm.org. All requests should be in the body, and look like such subscribe anchorage-pm-list unsubscribe anchorage-pm-list From pisium at yahoo.com Tue Mar 20 17:12:39 2001 From: pisium at yahoo.com (Rick J) Date: Wed Aug 4 23:56:49 2004 Subject: some puzzles In-Reply-To: <3AB7ADE7.406648AC@tara-lu.com> Message-ID: <20010320231239.93980.qmail@web13301.mail.yahoo.com> Thank you, Rox! Your explanation is very helpful to me. However, I double checked 2. $var = (10, 20, 30); $var is 30, not 3. I ran it on Unix and NT. It's same. About your extra examples: 6. $v1, $v2, $v3 = 10, 20, 30; 7. $v1, $v2, $v3 = (10, 20, 30); I guess it's due to the precedence of '=' ',', '()' Because () is higher than = than , precedencewise. Ex 6. It first evaluates $v3 = 10. After that, since '=' is used already, $v1, $v2 and 10, 20 become orphans, nowhere to assign the value. Ex 7. In parens on the right side, it evaluates the commas within the parens, and 30 is returned, and assigned $v3 after left side commas evaluation. Therefore if we print out the results for both like print "$v1:$v2:$v3"; Ex6. ::10 Ex7. ::30 If that's the case, it explains why in the context of $var = (10, 20, 30); we get $var = 30. Weird enough though. Rick __________________________________________________ Do You Yahoo!? Get email at your own domain with Yahoo! Mail. http://personal.mail.yahoo.com/ ================================================= Mailing list info: If at any time you wish to (un|re)subscribe to the list send the request to majordomo@hfb.pm.org. All requests should be in the body, and look like such subscribe anchorage-pm-list unsubscribe anchorage-pm-list From rox at tara-lu.com Tue Mar 20 17:47:45 2001 From: rox at tara-lu.com (Roxanne Reid-Bennett) Date: Wed Aug 4 23:56:49 2004 Subject: some puzzles References: <20010320194058.43161.qmail@web13307.mail.yahoo.com> <3AB7ADE7.406648AC@tara-lu.com> <20010320140438.A1639@shoebox.net> Message-ID: <3AB7EC21.187AC190@tara-lu.com> Michael Fowler wrote: >[...] > 6 and 7 don't make sense, and in fact aren't what I see with various > versions of Perl. What version of Perl are you using? well, it has more to do with how than version. I had put all of Rick's examples into a file and run them - I knew I was having a little bit of a problem of assignment and left over values, (which is why the vx1... series was introduced). Using the command line interface rather than rolling all the examples into one file (and allowing for re-use of already assigned values )... I get the same results you do for 6, and 7 was already the same. As to versions... Linux (a) 5.005_03 Linux (b) 5.6.0 NT 5.6.0 And 7 was the same between yours and mine. The differences were a matter of representation - vx1 was probably undefined - I didn't bother putting -w onto the perl line and put "" to describe the lack of value into the description because.. hmmm.. well - I just did. Rox -- Roxanne Reid-Bennett rox@tara-lu.com President, Tara-Lu Corporation http://www.tara-lu.com/ Quality brings its own reward. ================================================= Mailing list info: If at any time you wish to (un|re)subscribe to the list send the request to majordomo@hfb.pm.org. All requests should be in the body, and look like such subscribe anchorage-pm-list unsubscribe anchorage-pm-list From pisium at yahoo.com Tue Mar 20 19:41:20 2001 From: pisium at yahoo.com (Rick J) Date: Wed Aug 4 23:56:49 2004 Subject: some puzzles In-Reply-To: <3AB7D1E3.EDF1F46@tara-lu.com> Message-ID: <20010321014120.20164.qmail@web13305.mail.yahoo.com> Hi, Michael and Rox, Things are getting intersting now. First, thanks Michael. So the list assignment returns the number of elements assigned to the leftest scalar on the left side of the '=' as in $v1 = ($v2, @arr) = (10, 20, 30, 40); and $v1 is 4. OK. I know about closure. But here's the thing. Please look at this. 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 We first call callsub outside the while loop, and 1 is for sure. Then in the while loop, $num's assigned 10 outside sub block, and then increment by 1, that's second one - 11, then third one - 11 is after sub block. Now we are in the second loop, all the values are supposed to be discarded after first loop's done, right? But where's 12 from? I can deduce it easily from 11+1, but why when we print $num again outside sub block, it became 10 again?, and same thing happens in the third loop, 13 and 10. Why we can change the $num from outside sub (as 11/11 case), and can't carry the value inside sub outside(12/10 and 13/10)? Is it due to the elfish closure again? Sigh... Thanks, Ricky --- Roxanne Reid-Bennett wrote: > Michael Fowler wrote: > > > > > > However, running this through the Activestate > debugger, it does in fact > > > run through the callsub 3 times before executing > the $num = 10. > > > > Perl doesn't have scoped named subroutines, the > sub in the block is a bit > > misleading (and probably part of the source of his > confusion). When perl > > sees a named subroutine declaration the subroutine > is available almost > > anywhere. The only place it wouldn't be available > is in code being > > aha, ok. > > it didn't help that I read the following: > > > my $count = 0; > > callsub() while ($count++ < 3); > > { > ... > > } > > as (re-arranged a little bit to make my point) > > > my $count = 0; > > callsub(); > > while ($count++ < 3) > > { > ... > > } > > Makes a bit of a difference [and teaches me once > again to read the code as the > compiler does, not just read what I'm seeing and > make allowances for other > people's formatting ...] > > I had also totally forgotten the distinction between > arrays and lists. > > Thanks Michael. > > Rox > -- > Roxanne Reid-Bennett > rox@tara-lu.com > President, Tara-Lu Corporation > http://www.tara-lu.com/ > > Quality brings its own reward. > ================================================= > Mailing list info: If at any time you wish to > (un|re)subscribe to > the list send the request to majordomo@hfb.pm.org. > All requests > should be in the body, and look like such > subscribe anchorage-pm-list > unsubscribe anchorage-pm-list __________________________________________________ Do You Yahoo!? Get email at your own domain with Yahoo! Mail. http://personal.mail.yahoo.com/ ================================================= Mailing list info: If at any time you wish to (un|re)subscribe to the list send the request to majordomo@hfb.pm.org. All requests should be in the body, and look like such subscribe anchorage-pm-list unsubscribe anchorage-pm-list From pisium at yahoo.com Tue Mar 20 19:41:30 2001 From: pisium at yahoo.com (Rick J) Date: Wed Aug 4 23:56:49 2004 Subject: some puzzles In-Reply-To: <3AB7D1E3.EDF1F46@tara-lu.com> Message-ID: <20010321014130.91870.qmail@web13307.mail.yahoo.com> Hi, Michael and Rox, Things are getting intersting now. First, thanks Michael. So the list assignment returns the number of elements assigned to the leftest scalar on the left side of the '=' as in $v1 = ($v2, @arr) = (10, 20, 30, 40); and $v1 is 4. OK. I know about closure. But here's the thing. Please look at this. 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 We first call callsub outside the while loop, and 1 is for sure. Then in the while loop, $num's assigned 10 outside sub block, and then increment by 1, that's second one - 11, then third one - 11 is after sub block. Now we are in the second loop, all the values are supposed to be discarded after first loop's done, right? But where's 12 from? I can deduce it easily from 11+1, but why when we print $num again outside sub block, it became 10 again?, and same thing happens in the third loop, 13 and 10. Why we can change the $num from outside sub (as 11/11 case), and can't carry the value inside sub outside(12/10 and 13/10)? Is it due to the elfish closure again? Sigh... Thanks, Ricky --- Roxanne Reid-Bennett wrote: > Michael Fowler wrote: > > > > > > However, running this through the Activestate > debugger, it does in fact > > > run through the callsub 3 times before executing > the $num = 10. > > > > Perl doesn't have scoped named subroutines, the > sub in the block is a bit > > misleading (and probably part of the source of his > confusion). When perl > > sees a named subroutine declaration the subroutine > is available almost > > anywhere. The only place it wouldn't be available > is in code being > > aha, ok. > > it didn't help that I read the following: > > > my $count = 0; > > callsub() while ($count++ < 3); > > { > ... > > } > > as (re-arranged a little bit to make my point) > > > my $count = 0; > > callsub(); > > while ($count++ < 3) > > { > ... > > } > > Makes a bit of a difference [and teaches me once > again to read the code as the > compiler does, not just read what I'm seeing and > make allowances for other > people's formatting ...] > > I had also totally forgotten the distinction between > arrays and lists. > > Thanks Michael. > > Rox > -- > Roxanne Reid-Bennett > rox@tara-lu.com > President, Tara-Lu Corporation > http://www.tara-lu.com/ > > Quality brings its own reward. > ================================================= > Mailing list info: If at any time you wish to > (un|re)subscribe to > the list send the request to majordomo@hfb.pm.org. > All requests > should be in the body, and look like such > subscribe anchorage-pm-list > unsubscribe anchorage-pm-list __________________________________________________ Do You Yahoo!? Get email at your own domain with Yahoo! Mail. http://personal.mail.yahoo.com/ ================================================= Mailing list info: If at any time you wish to (un|re)subscribe to the list send the request to majordomo@hfb.pm.org. All requests should be in the body, and look like such subscribe anchorage-pm-list unsubscribe anchorage-pm-list From scot at ridgways.org Tue Mar 20 23:53:11 2001 From: scot at ridgways.org (Scot Ridgway) Date: Wed Aug 4 23:56:49 2004 Subject: some puzzles References: <20010321014130.91870.qmail@web13307.mail.yahoo.com> Message-ID: <003a01c0b1cb$369f2250$026ea8c0@ridgways.org> Rick, In your example callsub() is available globally, though you can only modify/access $num within the scope $num and callsub() were created.... like-a-so: { # scope one... my $num = 10; globally_accessible_sub(); # prints 1, undef + 1 } # scope two... my $num = 10; globally_accessible_sub(); # prints 2, while ($count++ < 1) { # scope three... my $num = 10; # while{} scope globally_accessible_sub(); # prints 11 sub globally_accessible_sub { print ++$num, "\n" } # we can modify $num in this scope $num = 20; # as we see below... globally_accessible_sub(); # prints 21 } # scope two, again... $num = 30; # but we can't access $num here... globally_accessible_sub(); # prints 22 Also you may have noted your were resetting $num to 10 within the while block via my $num = 10. -------------------------- --scot ----- Original Message ----- From: "Rick J" To: "Roxanne Reid-Bennett" Cc: Sent: Tuesday, March 20, 2001 4:41 PM Subject: Re: some puzzles > Hi, Michael and Rox, > > Things are getting intersting now. > > First, thanks Michael. So the list assignment returns > the number of elements assigned to the leftest scalar > on the left side of the '=' as in $v1 = ($v2, @arr) = > (10, 20, 30, 40); and $v1 is 4. OK. > > I know about closure. > > But here's the thing. Please look at this. > > 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 > > We first call callsub outside the while loop, and 1 is > for sure. Then in the while loop, $num's assigned 10 > outside sub block, and then increment by 1, that's > second one - 11, then third one - 11 is after sub > block. > Now we are in the second loop, all the values are > supposed to be discarded after first loop's done, > right? But where's 12 from? I can deduce it easily > from 11+1, but why when we print $num again outside > sub block, it became 10 again?, and same thing happens > in the third loop, 13 and 10. > Why we can change the $num from outside sub (as 11/11 > case), and can't carry the value inside sub > outside(12/10 and 13/10)? Is it due to the elfish > closure again? > > Sigh... > > Thanks, > Ricky > > --- Roxanne Reid-Bennett wrote: > > Michael Fowler wrote: > > > > > > > > However, running this through the Activestate > > debugger, it does in fact > > > > run through the callsub 3 times before executing > > the $num = 10. > > > > > > Perl doesn't have scoped named subroutines, the > > sub in the block is a bit > > > misleading (and probably part of the source of his > > confusion). When perl > > > sees a named subroutine declaration the subroutine > > is available almost > > > anywhere. The only place it wouldn't be available > > is in code being > > > > aha, ok. > > > > it didn't help that I read the following: > > > > > my $count = 0; > > > callsub() while ($count++ < 3); > > > { > > ... > > > } > > > > as (re-arranged a little bit to make my point) > > > > > my $count = 0; > > > callsub(); > > > while ($count++ < 3) > > > { > > ... > > > } > > > > Makes a bit of a difference [and teaches me once > > again to read the code as the > > compiler does, not just read what I'm seeing and > > make allowances for other > > people's formatting ...] > > > > I had also totally forgotten the distinction between > > arrays and lists. > > > > Thanks Michael. > > > > Rox > > -- > > Roxanne Reid-Bennett > > rox@tara-lu.com > > President, Tara-Lu Corporation > > http://www.tara-lu.com/ > > > > Quality brings its own reward. > > ================================================= > > Mailing list info: If at any time you wish to > > (un|re)subscribe to > > the list send the request to majordomo@hfb.pm.org. > > All requests > > should be in the body, and look like such > > subscribe anchorage-pm-list > > unsubscribe anchorage-pm-list > > > __________________________________________________ > Do You Yahoo!? > Get email at your own domain with Yahoo! Mail. > http://personal.mail.yahoo.com/ > ================================================= > Mailing list info: If at any time you wish to (un|re)subscribe to > the list send the request to majordomo@hfb.pm.org. All requests > should be in the body, and look like such > subscribe anchorage-pm-list > unsubscribe anchorage-pm-list > ================================================= Mailing list info: If at any time you wish to (un|re)subscribe to the list send the request to majordomo@hfb.pm.org. All requests should be in the body, and look like such subscribe anchorage-pm-list unsubscribe anchorage-pm-list From michael at shoebox.net Wed Mar 21 12:01:58 2001 From: michael at shoebox.net (Michael Fowler) Date: Wed Aug 4 23:56:49 2004 Subject: some puzzles In-Reply-To: <20010321014130.91870.qmail@web13307.mail.yahoo.com>; from pisium@yahoo.com on Tue, Mar 20, 2001 at 05:41:30PM -0800 References: <3AB7D1E3.EDF1F46@tara-lu.com> <20010321014130.91870.qmail@web13307.mail.yahoo.com> Message-ID: <20010321090158.A1826@shoebox.net> 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@hfb.pm.org. All requests should be in the body, and look like such subscribe anchorage-pm-list unsubscribe anchorage-pm-list