From: Ted Zlatanov on
On Thu, 24 Apr 2008 09:31:05 -0700 (PDT) Ted <r.ted.byers(a)rogers.com> wrote:

T> She is a gem, isn't she?!!

Abigail's gender should be in the FAQ :)

T> I learned plenty about the perl side of things from her posts. And I
T> found Ben's last example, using undef to ignore certain values,
T> interesting. But his first example remains problematic. Between the
T> two, and others, I can see some logic in choosing undef as a pel
T> primitive to represent SQL NULLS, but it seems to me that with the
T> support now available for object oriented programming in perl, it
T> would have been relatively trivial to provide a new class to more
T> closely represent the SQL idea of a null. When I did it in Java, all
T> I had to do was add a private data member of type boolean, and then
T> check this data member in those member functions where it is relevant
T> that override functions provided in the relevant base classes.

Objects in Perl are not always the right solution. undef takes a lot
less memory than a blessed object, for example, and it's faster. Also,
it's annoying if you just want to deal with values (compare with Java's
painfully horrible Integer vs. int hack, repeated for a bunch of
primitives).

Like I said, it's a compromise. By definition some people won't like
it. I think it's the right thing in the context of Perl, and obviously
most people like the DBI as it is or it would have been changed long
ago. I would address it by adding a DBI function is_null() that can be
attached to a row somehow, so you can say

while (my $row = ...)
{
if (is_null($row, $column)) { ... } # doesn't matter how is_null is invoked
}

T> BTW: having read the thread, you see where Ben and I seem to be
T> butting heads. Can you point me to places in the Perl reference that
T> substantiate his perspective on the points where we disagree, and
T> which provide a fuller explanation of his point of view?

I'm not sure what exactly you're asking. I don't think Ben said
anything wrong, and I don't think (but could be wrong) there's a
specific reference document on the topic you were discussing. There's
bits and pieces all over. I think Ben would have pointed you to the
right document already if it was in one place.

Ted
From: Ted Zlatanov on
On Thu, 24 Apr 2008 12:57:09 -0700 (PDT) Ted <r.ted.byers(a)rogers.com> wrote:

T> He objected most strenuously to the notion that [undef] refers to an
T> uninitialized variable, even though his first example clearly used an
T> uninitialized variable to illustrate the idea of undef. The second
T> is that he maintains that the empty string is the idea of a defined
T> null, and that that is something Wall et al. were referring to.

I'll illustrate with code.

use Data::Dumper;

my $null; # uninitialized variable
my $one = 1;
my $formerly_defined = 1;
undef $formerly_defined;
foreach my $check (1, 0, '0', '0.00', '', $null, $one, undef, $formerly_defined)
{
print $check ? 'true' : 'false';
print ', ';
print defined $check ? 'defined' : 'not defined';
print ', ';
print 'value = ', Dumper($check);
}

This produces:

true, defined, value = $VAR1 = 1;
false, defined, value = $VAR1 = 0;
false, defined, value = $VAR1 = '0';
true, defined, value = $VAR1 = '0.00';
false, defined, value = $VAR1 = '';
false, not defined, value = $VAR1 = undef;
true, defined, value = $VAR1 = 1;
false, not defined, value = $VAR1 = undef;
false, not defined, value = $VAR1 = undef;

See how $formerly_defined has been initialized to 1, then undefined.
It has been set twice, the second time to the undefined value. This is,
I think, what Ben meant.

I don't know if this is in a single place in the docs, but see `perldoc
perltrap' `perldoc perlsyn' `perldoc perlnumber' among others.

T> I don't have a problem regarding the empty string as a defined null
T> string, if that's the way things are defined in Perl

Basically the rules above are what they are, and are essential to Perl's
DWIM. The DBI, to get back to the point of the thread, does the best it
can with what's available. You can't get an undef back unless the value
is NULL, so really your problem is in the further treatment of the undef
vs. how SQL would treat the NULL. That Perl behavior is not likely to
change in the future, so either use the undef and know the effects, or
wrap it in your own classes that do the right thing for your needs.

T> That you saw nothing wrong in what Ben wrote would suggest to me that
T> he is drawing on a common belief in the perl programming community,
T> and it seems to me that there remain things here to be explained in
T> more detail.

I don't think it's productive to direct the argument at Ben. Say what's
still unclear and we'll clear it up. Code always is more precise than
words, so ask about code if possible.

Ted
From: Ben Bullock on
Ted Zlatanov <tzz(a)lifelogs.com> wrote:

> See how $formerly_defined has been initialized to 1, then undefined.
> It has been set twice, the second time to the undefined value. This is,
> I think, what Ben meant.

It's partly what I meant. It's incorrect to think of Perl's
"undefined" value as being equivalent to an uninitialized variable in
many other ways. For example

return;

in a scalar context gives an "undefined" result, but the "undefined"
here has absolutely nothing to do with something not being
initialized.

"Undefined" in Perl is a kind of flag which tells you something about
a situation, like your subroutine gave up halfway through, or your
hash or array variable doesn't exist, or maybe you have a NULL in your
SQL table. Undefined doesn't behave exactly like a pointer to zero in
C++, an uninitialized variable in C++, or a zero-length (i.e. '\0'
terminated) array of characters in C++. I don't see the point in
trying to make a more and more tortured analogy between Perl's
undefined value and concepts from another language. To understand what
"undef" is in Perl you need to look at what Perl does with it.