2

I would expect the block in the second 'if' statement to be entered because of the undef value but the logs show that it isn't being entered.

sub getcmd{
  my $self = $_[0];
  if ( $self->_recv == OK ){
      push @{$self->{'log'}}, ['NOTICE', "OK"];
      return "My command";          
  }
  push @{$self->{'log'}}, ['ERROR', "Did not get OK back"];
  return undef;
}

...

if (!($ret = $self->getcmd)){
  push @{$self->{'log'}}, ['ERROR', "failed to read after asking for NEXT"];
}
else {
  push @{$self->{'log'}}, ['ERROR', "'undef' not detected in next()"];
}

The log file shows:

[Fri May  8 19:25:56 2009]: ERROR: Did not get OK back
[Fri May  8 19:26:02 2009]: ERROR: 'undef' not detected in next()

Any ideas gratefully accepted.

Edit: Sorry, I'd edited down the code to show the basic flow. I should've proofread it a bit better.

  • I added the $ret in getcmd() to simulate what happens in the logging function which just prints out the current value of $ret which is a global variable always used to capture return values.
  • I'd trimmed down the log messages and missed the extra "back"

Thanks for the suggestions and comments. I hadn't noticed the six second difference in the log timestamps so now I suspect that you're right about the execution sequence being different to what I originally expected.

I'll go back and look again. Guess that's what you get when trying to look at someone else's "average" Perl after a thirteen hour day trying to get things finished for a "must go live on Monday" project!

I didn't write the code and simply inherited it. The code was written by a couple of people who think they don't "need no steenking warnings or stricts".

Imagine 800 lines of Perl and lots of 'ifs' but no else statements! No defensive coding at all! 8-O

brian d foy
  • 129,424
  • 31
  • 207
  • 592
Rob Wells
  • 36,220
  • 13
  • 81
  • 146
  • 1
    Just a little thing: the difference in timestamps makes me suspicious that actually there's a lot more code between the call to getcmd() and the 2nd log statement -- is the code exactly as you have presented? – j_random_hacker May 09 '09 at 14:29
  • 1
    I'm confused by $ret being used and not declared in getcmd. And what is its actual value in the if/else? – Anonymous May 09 '09 at 14:34
  • 2
    The first log message didn't come from the getcmd function you show; the message says "back back" and the code doesn't. – Jonathan Leffler May 09 '09 at 14:39
  • 1
    @Anonymous: it could be that $ret is a package or global variable. It could be the code is not running under 'use strict;' and '-w' (aka 'use warnings;'). – Jonathan Leffler May 09 '09 at 14:47

4 Answers4

7

Reduced to a bare minimum, this prints "undef detected".

#!/bin/perl -w

use strict;

sub getcmd
{
    return undef;
}

my $ret;

if (!($ret = getcmd()))
{
    print "undef detected\n";
}
else
{
    print "undef undetected\n";
}

Consequently, your problem is most likely that the $self->getcmd() isn't returning undef, even though you think it should.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
2

I think something more complicated is going on here -- those log messages seem to be 6 seconds apart, and there's no way it'd take 6 seconds for the push statement, the return, and the if check.

Any chance the first log message was from a previous call of the method from some other place in the application?

Jonathan Rupp
  • 15,522
  • 5
  • 45
  • 61
1

Use perl debugger (perl -d) to step through the code to see what is going on. When debugging code, it's important to free your mind from every assumption.

Also, these lines are a must above every perl program:

use strict;
use warnings;
amarillion
  • 24,487
  • 15
  • 68
  • 80
0

The proper way to test $var for undef is not if (!$var) ..., because the test will also be true for $var = '' and $var = 0. Use if (!defined $var) ... instead.

Maybe like this (showing all relevant cases):

if (!defined $var) {
    # not defined ...
} elsif ($var) {
    # defined and true...
} else {
    # defined and false
}
U. Windl
  • 3,480
  • 26
  • 54