http://www.perlmonks.org?node_id=11104623


in reply to The error says the value is uninitialized, but it works anyway

Other monks have explained where the undef values are coming from, but have not explained why your program still works despite the warnings. Since you were honest about this being a homework assignment, I will take some time to explain.

Your program works anyway because neither of the elements in @drop are undef, and while undef eq undef (with two warnings) in Perl, undef ne $string if $string is a defined true value.

Here is the contents of the @colors array on each iteration of the loop, both before and after an element is possibly removed. The element that $num refers to is underlined.

0: before: red green blue yellow pink purple brown
0:  after: red green blue yellow pink purple brown
--
1: before: red green blue yellow pink purple brown
1:  after: red green blue yellow pink purple brown
--
2: before: red green blue yellow pink purple brown
2:  after: red green blue yellow pink purple brown
--
3: before: red green blue yellow pink purple brown
3:  after: red green blue yellow pink purple brown
--
4: before: red green blue yellow pink purple brown
4:  after: red green blue yellow purple brown
--
5: before: red green blue yellow purple brown
5:  after: red green blue yellow purple
--
6: before: red green blue yellow purple
6:  after: red green blue yellow purple
--

I modified the code slightly to print that. While I cannot show you exactly what I used without giving away an answer that you should find, this code shows what the "before" and "after" parts mean:

my @colors = qw(red green blue yellow pink purple brown); my $count = @colors; my @drop = qw(pink brown); my $num = 0; foreach $num (1..$count){ $num--; print $num, ": before: @colors\n"; if ($colors[$num] eq $drop[0] or $colors[$num] eq $drop[1]){ splice (@colors, $num, 1); } print $num, ": after: @colors\n--\n"; } print "@colors \n";

This technique of inserting additional output to show a program's intermediate states is commonly known as "printf debugging", after the common output function in the C programming language. Perl also has printf, but print is far more commonly used.

The bug in your code that haukex mentioned should be easy to see now, and I will give a few hints towards the "two lines of code" that haukex mentioned:

  1. How do you construct a hash from a list in Perl?
  2. How can you use map to construct such a list?
  3. How do you test for the existence of a hash key?
  4. What does grep do in Perl?

And another issue:

  1. How can you avoid the wasted seventh iteration of the loop? (Hint: What are the loop control operators in Perl?)

Good luck on your adventures in learning Perl.

Edited 2019-08-18 by jcb: Fix logical error pointed out by haukex: undef is not special under eq and stringifies to an empty string.