in reply to why can't compare a variable with undef directly?

Because operators == and != force numeric context on their operands.

Add use warnings to your code and it will start working properly

Use of uninitialized value in numeric ne (!=) at w.pl line 8. Argument "Hi" isn't numeric in numeric ne (!=) at w.pl line 8. Use of uninitialized value in numeric ne (!=) at w.pl line 9. Argument "" isn't numeric in numeric ne (!=) at w.pl line 9. Use of uninitialized value in numeric ne (!=) at w.pl line 10. Use of uninitialized value in numeric ne (!=) at w.pl line 11. $number is defined