defining undef

Dieser Post wurde aus meiner alten WordPress-Installation importiert. Sollte es Darstellungsprobleme, falsche Links oder fehlende Bilder geben, bitte einfach hier einen Kommentar hinterlassen. Danke.

MS-DOS basic variants had fixed default values for variables, "empty" for string variables and "0" for numbers. DATABUS (now DB/C) variables used to have unpredictable content unless initialized with an empty value and Pascal - as far as I remember - also had default values. Perl doesn't distinguish between text and numbers but it has a default value for all scalars: undef.

A "undef" variable isn't something bad or a crash reason, it's basically an additional value besides an "empty string" and "0". "undef" behaves like both of them depending on the context: In string context, it's empty and counts zero in numerical context. Sounds complicated, but actually it's very easy because an "empty variable" always behaves the way you expect it to do. Beginners don't need to know anything about "undef", because they don't need to care.

Having undef allows developers to check for defined $x and actually know if a variable

  • hasn't been used/filled before or has been set to undef
  • is an empty string
  • is 0.
One could say that every variable must be initialized before it is used and working that way eases parameter checks:
sub a {  my $x = shift;  die 'Undefind x' unless defined $x;
Every undef value is an error. Very simple and actually, this point of view became a holy law for Perl.

Perl doesn't fail on undefined values and I assume two reasons for this:

  1. Perl always has been backward compatible (compared to other languages, some of them used to have "Perl" in their name), failing on undef would break this rule.
  2. Perl is the pure perfection of TIMTOWTDI, really enforcing defined values would limit the number of ways, something might be done by an unacceptable number.

Complain or not?

But Perl has warnings and one of the most common ones is Use of uninitialized value $x in... Some operations accept "undef" values, like boolean comparisons or the ref() function (which has been copied by JavaScript and is called typeof() there).

These warnings have advantages and disadvantages. People used to treat "undef" as an expected state don't care unless they need to do for some reason and their scripts start throwing a lot of warnings if "use warnings;" is added to the source. Web projects usually don't care if a query argument is missing or has an empty value and source might start getting a lot of ($x // '') constructs meaning "use the value of $x or an empty string if $x is undefined" which is syntactically correct and separates variables which might be "undef" from some which aren't expected to be, but it clearly degrades readability of the source.

Not every warning is noise, some really show up variable which are "undef" where they're not allowed to be, hopefully before the missing value is doing any harm. Sometimes adding a value check (and not skipping the warning using // ) is much better than anything else. (Yes, everything should verify the values it's working with and yes, those checks are very rare in real life.)


Common sense

I joined a new project this week and they're using the CPAN module common::sense which actually disables "undef" complains by default. The authors say:
undef is a well-defined feature of Perl, and enabling warnings for using it rarely catches any bugs, but considerably limits you in what you can do, so uninitialized warnings are disabled.
I agree with them 100% and thought about suggesting a no warnings 'uninitialised'; as default for my main project. I was really unsure, but finally decided to keep the undef warnings, actually because I agree with the common::sense authors. They say that it rarely catches any bugs and thats exactly what I saw in the past within our project: Most Use of uninitialized value are no bugs, but some are - and I remember some cases where those warnings pointed me to a bug which had the potential of causing a huge business impact with a lot of money getting burned.

I won't turn the warnings off for now but might consider it for future projects.


Noch keine Kommentare. Schreib was dazu

Schreib was dazu

Die folgenden HTML-Tags sind erlaubt:<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>