Re: Interesting behaviour with lexical variable



Ferry Bolhar wrote:

Hi to all,

while playing with code like this:

use warnings;
while (my $input = <STDIN>){
my $num = abs $input;
print add();

sub add {
$num + $num;
}
}

Unless you really know what you're doing, you should never define a
function inside a loop or another function. In fact, many Perl
programmers (me included) recommend that all your functions be defined
at the top of your script, before you start your main code. Do that,
and your problem will go away.

I found out that once the loop get executed for the second
time, the variable $sum gets "splitted", taking the new value
from $input in the loop, but leaving the old, previous value
in add().

I believe that's because the add() function is never defined until
the first time through the loop. Once it gets defined, it uses the
current value of $num in its return value, which appears to go out of
scope at the end of the loop. However, a reference is still retained
(by the add() function), so $num (declared the first time time through
the loop) never completely goes out of scope, as it is retained by the
add() function.

So the second (and subsequent) times through the loop, a new $num is
created, which is a DIFFERENT instance of the one that the add()
function uses (remember: the add() function uses the very first
instance of $num). It never stops using that first instance of $num,
which is why the add() function will always return the same thing.

You may mistakenly think that the add() function will always use the
latest value of $num, but it won't: the add() function only needs to
be defined once, and after that it never gets defined again. So it
never stops using the first instance of $num.

If this sounds confusing, it's because it kind of is. But change
your coding style so that all your functions are defined before your
main code (and not in any loops or functions either), and you should
never encounter this problem again.

I hope this helps, Ferry.

-- Jean-Luc

.



Relevant Pages

  • Re: count occurences of font color
    ... Dim num As Long, res As Long ... Debug.Print Timer - s ... ' using isnull and not using characters ... as the loop will exit on the first character. ...
    (microsoft.public.excel.programming)
  • Interesting behaviour with lexical variable
    ... use warnings; ... I found out that once the loop get executed for the second ... sub main { ... Variable "$num" will not stay shared at x.pl line 11. ...
    (comp.lang.perl.misc)
  • Re: count occurences of font color
    ... Dim num As Long, res As Long ... Debug.Print Timer - s ... ' using isnull and not using characters ... as the loop will exit on the first character. ...
    (microsoft.public.excel.programming)
  • Re: WHILE LOOP NOT WORKING IN INCLUDE ASP FILE - LOOPING FOREVER
    ... I have an issue with the while loop in include file. ... I see that the ONLY field you are using is the NUM ... Change the query ... provided by the recordset, Bottom line: you do not need a cursor. ...
    (microsoft.public.data.ado)
  • Re: threads question
    ... loop) before process 2 ever gets started. ... i is already equal to 5 so the while loop never executes and num ... time slice is up and process 1 runs again. ... Mr. Bazarov points out, C++ has no help for you. ...
    (comp.lang.cpp)