Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Re: User of uninitialized value #1512

Closed
p5pRT opened this issue Mar 28, 2000 · 2 comments
Closed

Re: User of uninitialized value #1512

p5pRT opened this issue Mar 28, 2000 · 2 comments

Comments

@p5pRT
Copy link

p5pRT commented Mar 28, 2000

Migrated from rt.perl.org#2729 (status was 'resolved')

Searchable as RT2729$

@p5pRT
Copy link
Author

p5pRT commented Mar 28, 2000

From gnat@frii.com

Nicolas MONNET writes​:

my $a = undef;
my $b = 'gelp';
$a ne $b and print "fuck";
Use of uninitialized value at - line 3.
fuck[nico@​nico nico]$

This warning does'nt make sense. $a is perfectly initialized. The 'undef'
value has a meaning. Comparing to it makes sense.

You're right, "use of uninitialized value" should really be "use of
undefined value". The "uninitialized" part comes from the warning's
most common manifestation​:

  # $x is never given a value
  if ($y eq $x) { print "same" }

Many Perl functions use undef as an error value (e.g., <FH> to read
from a filehandle). At runtime, Perl can't tell the difference between
undef resulting from never giving a variable a value, undef resulting
from a function returning undef, and undef resulting from your writing
$x = undef.

And it shouldn't. In all three cases, you've given a value to a
variable that isn't a string. If you use eq to compare an undefined
value, you're doing something wrong. Perl tries to make sense of it
by using "" as the string value for undef, but it's still highly
suspicious.

And the POINT of -w is to warn on suspicious things.

HOWEVER, computing with it does'nt​:

$a = undef; $a++;
$a = undef; $c = $a+2;
$a = undef; $a .= ' ';

THOSE should all put warnings.

The first and last do not print a warning because ++ is special-cased
to avoid warnings. It's a pain in the butt to have to keep saying
"have I seen this thing before? If not, initialize it". So ++
doesn't give uninitialized value warnings. It's designed for loops
like this​:
  while (<>) {
  $seen{$_}++;
  }

The middle one *does* emit a warning. You're treating undef like a
number, and it's not a number. If you use ++, or += or .= or any
of the operators that modify their LHS, you won't get the warning.
Any other use of undef as though it were a string or a number will
emit warnings.

In 5.6, warnings are customisable. You can turn off individual
warnings for a region or the entire program with the "warnings"
pragma​:

  use warnings;
  { no warnings "initialized";
  if ($x eq $y) { ... }
  }

but I remind you that almost every use of undef as though it were
a string is wrong wrong wrong.

However, it's probably way too late to change the name of
uninitialized value, as people may have written code that expects
to ignore these warnings.

Nat

@p5pRT
Copy link
Author

p5pRT commented Mar 28, 2000

From [Unknown Contact. See original ticket]

On Mon, 27 Mar 2000, Nathan Torkington wrote​:

|You're right, "use of uninitialized value" should really be "use of
|undefined value". The "uninitialized" part comes from the warning's
|most common manifestation​:
|
| # $x is never given a value
| if ($y eq $x) { print "same" }

I don't know the perl internals well enough, HOWEVER, should'nt it be that
this kind of warning be issued when a new variable is created in memory as
an r-value?

Example​:

$a = 'sumthin';
$test = undef; # here a new variable is created in memory
if ($a eq $test) { }

... should be fine ...

but

$a = 'sumthin';
$test = 'sumthinelse';
if ($a eq $tset) { } #speling error causing a new variable to
  # be instantiated, likely to be an error

... should output a warning, should'nt it?

|but I remind you that almost every use of undef as though it were
|a string is wrong wrong wrong.

Case in point​: DBI returns undef for SQL NULL. Say you want to see if the
cell is equal to some special value​:
$cell = ($sth->fetchrow_array)[0];
if ($cell eq 'specialvalue') {
  print "specialvalue";
}

In this case, you don't care if $cell is undef or not. I fail to see how,
in a comparison, it may lead to any kind of problem (I can be wrong).
However, using the value as if it was a string, as implied, for example
by​: $a = $cell." is the value."; should yield a warning.

Note​: I'm not trying to have Perl's behavior changed, just to point out
why warnings are a pain in the ass and why I don't use them most of the
time. Adding tests for definedness in that type of cases is much much more
trouble than the few occasions where I misspelled a variable name that
ended up throwing a warning.

|However, it's probably way too late to change the name of
|uninitialized value, as people may have written code that expects
|to ignore these warnings.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant