in reply to Surprising result when using undef

Perl's undefined value becomes the empty string if coerced to a string, and the empty string becomes zero if coerced to a number. Therefore, an undefined value will compare equal to zero in numeric comparison. Perl can emit warnings whenever an undefined value is coerced, as you have found.

The smallest change to fix your code is to change the undef on line 17 to 1, thus changing the default value if is_dev_mode is not given to a true value instead of an undefined value.

Alternately, as another monk suggested, change is_dev_mode to is_live and simply load my $is_live = $param->{is_live}; in the prologue. If the is_live key is not given, that will set $is_live to undef, and undef is false in boolean context, without a warning.