http://qs321.pair.com?node_id=344237


in reply to Re: CamelTrouble
in thread CamelTrouble

Everythime I pick up a dude, I see... Use of uninitialized value in subtraction (-) at CamelTrouble.perlmonks343196.pl line 286. Use of uninitialized value in addition (+) at CamelTrouble.perlmonks343196.pl line 286.
That's right. It's one of the bugs I mentioned in the description. Unfortunately I don't know how to fix it. Please help :-)
My camels seem to have no problem walking through walls, which makes avoiding the hazards to get to the Oasis after picking up all the dudes very easy.
As I explained above, the camel doesn't walk through the wall, it jumps over it ;-)

Replies are listed 'Best First'.
Re: Re: Re: CamelTrouble
by Vautrin (Hermit) on Apr 11, 2004 at 18:03 UTC

    If you use warnings; you can use no warnings qw(foobar); in a block to turn off the foobar type warning. So you could do:

    no warnings qw(uninitialized);

    Or you could check your code, i.e.:

    # so it's not undefined: $foo = 0 unless (defined $foo);

    I put a big write up on my scratchpad for somebody about using use warnings for fine grained control. Check it out if you're interested.


    Want to support the EFF and FSF by buying cool stuff? Click here.
Re: Re: Re: CamelTrouble
by hossman (Prior) on Apr 11, 2004 at 18:39 UTC

    Well, I haven't read all of your code, so I can't say authoritatively that I know exactly what the bug is, but i have read the good_ones_go funtion, and fortunately your program is nice and moduler, and your variables names are fairly clear, (the only thing i needed to look up anywhere else in the script is what "@good_ones" contains, and what you pass to "good_ones_go" when you call it) so I think I have a pretty good idea what's going wrong.

    Rather then just fixing it for you, let me ask you a question, what happens if you run this script....

    # perl use warnings; use strict; my @good_ones = (100..110); foreach (0..$#good_ones) { print "$_: $good_ones[$_] ..."; if (rand() < 0.5) { splice @good_ones,$_,1; } print "($#good_ones)\n"; }

    (PS: you may be tempted to "fix" your script by adding a single call to "last;" ... I wouldn't recommend that. Consider what would happen if the camel moves one pixel, and that puts him close enough to pick up two monks.)

      Thanks for the snippet! And thank you for NOT telling me how to fix it, I love sleepless nights ;-)
      After this night I read Vautrin's reply (after, very clever :-/) and tried this
      ... foreach (0..$#good_ones) { if (defined $good_ones[$_]) { print ... ...
      The error messages are gone. Is this the solution? Maybe I'm silly, but I still have no idea why the code produced an error massage at all.

        That's certainly a valid solution, but of course TMTOWTDI

        As for why the code produced the error in the first place, you are starting with an array of N elements, and you are iterating over a list of the indexes of the elements in that array. But while you iterate over those elements, you are deleting them from the orriginal array, which shortens it, but you've still got the indexes, so as you get to the end of your list of indexes, the last few indexes may not exist in the array anymore.

        Ie: if $#good_ones is 9, and the camel picks up $good_ones5 and you splice it out of the list, then when that foreach loop reaches 9, $good_ones9, it's going to be undef (because it's off the end of the array)

        Another valid solution would be to change your foreach(0..$#good_ones) to for(my $_=0;$_<=$#good_ones;), and only increment $_ if you do NOT splice the array. In that case, $#good_ones will be evaluated on each pass of the loop, and it will do the right thing as the array gets shorter and shorter.