very strange conditional problem

K

Kodeguru

** I also posted this in comp.lang.perl **


I just finished debugging a very strange problem, and was wondering if
any of you had ever seen it before. My code is very long, so I will only
post the interesting parts.

ok, so using DBD::Sybase and some other stuff, we do a select query on a
database and store the return like this:

#####------######

$sql = "SELECT blah blah blah";

$sth = $dbh->prepare();

$sth->execute();

while (my $equip_row = $sth->fetchrow_arrayref()){

# ....

# this line prints $equip_row->[16] is ([email protected])\n
# which is right
print "\$equip_row->[16] is ($equip_row->[16])\n";

if ($equip_row->[16] != undef){ # But then this test fails

# and this line doesn't print at all
print "$equip_row->[16] is not undef, so...\n";

# sends email
# ....

}
}


#####------######

Now if I change the line where the conditional is to

if ($equip_row->[16] =~ /\S+/) {

It works. Both debug lines print like they should and the emails get sent.

The code is working now, because I left it as a regex test, but this is
the craziest thing I've ever seen. I looked at it for hours, and I don't
think I'm missing anything stupid.

Anyone else have any ideas ?
 
K

ko

Kodeguru said:
** I also posted this in comp.lang.perl **

I just finished debugging a very strange problem, and was wondering if
any of you had ever seen it before. My code is very long, so I will only
post the interesting parts.

ok, so using DBD::Sybase and some other stuff, we do a select query on a
database and store the return like this:

#####------######

$sql = "SELECT blah blah blah";

$sth = $dbh->prepare();

$sth->execute();

while (my $equip_row = $sth->fetchrow_arrayref()){

# ....

# this line prints $equip_row->[16] is ([email protected])\n
# which is right
print "\$equip_row->[16] is ($equip_row->[16])\n";

if ($equip_row->[16] != undef){ # But then this test fails
------------^^^^^^^^^^^^^^^^^^^^^^^^^^

The != operator expects *numeric* operands/arguments. Both
$equip_row->[16] and undef are converted to numbers. So basically what
happens is:

if ( 0 != 0 ) {
# and this line doesn't print at all
print "$equip_row->[16] is not undef, so...\n";

That's why this block never gets executed.
# sends email
# ....

}
}


#####------######

[snip]

HTH -keith
 
K

Kodeguru

ko said:
The != operator expects *numeric* operands/arguments. Both
$equip_row->[16] and undef are converted to numbers. So basically what
happens is:

if ( 0 != 0 ) {
# and this line doesn't print at all
print "$equip_row->[16] is not undef, so...\n";


That's why this block never gets executed.
# sends email
# ....

}
}


#####------######


[snip]

HTH -keith

I tried it with ne as well, as in

if ($equip_row->[16] ne undef){

and that didn't work either.
 
K

Kodeguru

Kodeguru wrote:

I tried it with ne as well, as in

if ($equip_row->[16] ne undef){

and that didn't work either.


Hmm,
no, perhaps I'm mistaken. Maybe I didn't try it with 'ne'.

Thanks.
 
K

ko

Kodeguru said:
Kodeguru wrote:

I tried it with ne as well, as in

if ($equip_row->[16] ne undef){

and that didn't work either.


Hmm,
no, perhaps I'm mistaken. Maybe I didn't try it with 'ne'.

Thanks.

You probably don't want to use this type of construct anyway, since it
triggers a warning - you do have warnings enabled right? :)

Its more common to use something like:

if ( defined $equip_row->[16] ) {
...

keith
 
T

Tad McClellan

ko said:
Kodeguru wrote:
if ($equip_row->[16] != undef){ # But then this test fails
------------^^^^^^^^^^^^^^^^^^^^^^^^^^

The != operator expects *numeric* operands/arguments. Both
$equip_row->[16] and undef are converted to numbers. So basically what
happens is:

if ( 0 != 0 ) {

That's why this block never gets executed.


You should always enable warnings when developing Perl code!

Kodeguru has wasted a bunch of man-minutes by asking thousands
of people around the world to troubleshoot a problem that a
machine could have spotted in a small part of a single second!

Please do not ask people to do the work of a machine,
they won't like it.
 
J

J. Romano

Kodeguru said:
# this line prints $equip_row->[16] is ([email protected])\n
# which is right
print "\$equip_row->[16] is ($equip_row->[16])\n";

if ($equip_row->[16] != undef){ # But then this test fails

# and this line doesn't print at all
print "$equip_row->[16] is not undef, so...\n";

#####------######

Now if I change the line where the conditional is to

if ($equip_row->[16] =~ /\S+/) {

It works. Both debug lines print like they should and the emails get sent.

Anyone else have any ideas ?

I have an idea, even though I do not know the exact reason why your
code is not working as you'd expect.

My thought is that your Perl interpreter doesn't like comparing a
scalar to undef. Therefore, I suggest that, instead of comparing a
scalar to see if it doesn't equal undef, try seeing if it is defined
by using the "defined" keyword. Try changing the condition:

if ($equip_row->[16] != undef)

to this one:

if (defined($equip_row->[16]))

See if that works.

Happy Perling!

-- Jean-Luc
 
J

J. Romano

Kodeguru said:
** I also posted this in comp.lang.perl **

# this line prints $equip_row->[16] is ([email protected])\n
# which is right
print "\$equip_row->[16] is ($equip_row->[16])\n";

if ($equip_row->[16] != undef){ # But then this test fails

#####------######

Now if I change the line where the conditional is to

if ($equip_row->[16] =~ /\S+/) {

It works. Both debug lines print like they should and the emails get sent.

The code is working now, because I left it as a regex test, but this is
the craziest thing I've ever seen. I looked at it for hours, and I don't
think I'm missing anything stupid.

Anyone else have any ideas ?

Okay, I think the answer just came to me. The reason the condition

if ($equip_row->[16] != undef)

always fails is because you are using the != operator (instead of
"ne") to make a comparison, which will always compare numerical
values. As a result, $equip_row->[16] evaluates to zero (since it is
just text with no digits), and so does undef. Then the condition is
basically equivalent to:

if (0 != 0)

which, of course, will always fail. You should change that condition
to be:

if (defined($equip_row->[16]))

or just:

if ($equip_row->[16])

since an undefined value will always evaluate to false.

Hope this helps!

-- Jean-Luc Romano
 
C

Chris Charley

Kodeguru said:
** I also posted this in comp.lang.perl **

if ($equip_row->[16] != undef){ # But then this test fails

Should be: if (defined $equip_row->[16])

HTH,
Chris
 
K

Kodeguru

Thank you all,


I did have warnings turned on, but it just didn't seem to help. The
warning I got didn't seem to explain the problem, and it is just a
"warning". I'm sorry to have wasted all of your man minutes.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,900
Latest member
Nell636132

Latest Threads

Top