Why does DBI's do method return "0E0" if zero rows were affected?

I ran into a problem when running code similar to the following example:

my $rows = $dbh->do('UPDATE table SET deleted=NOW() WHERE id=?', undef, $id) 
  or die $dbh->errstr;
if (!$rows) {
  # do something else
}

Since the docs state that do returns the number of rows affected, I thought that would work.

Prepare and execute a single statement. Returns the number of rows affected or undef on error. A return value of -1 means the number of rows is not known, not applicable, or not available.

As it turns out, I was mistaken. When I debugged it, I saw that $rows in fact holds the string 0E0, which of course is a true-ish value. I dug in the docs further and saw this piece of code:

The default do method is logically similar to:

  sub do {
      my($dbh, $statement, $attr, @bind_values) = @_;
      my $sth = $dbh->prepare($statement, $attr) or return undef;
      $sth->execute(@bind_values) or return undef;
      my $rows = $sth->rows;
      ($rows == 0) ? "0E0" : $rows; # always return true if no error
  }

There it is. It returns 0E0. I just don't get why it would do that. Does anyone know?

Answers


It's a true value, so you can distinguish it from the false value it returns on error, yet it's numerically equal to zero (without warning), so it's still equal to the number of records affected.

$ perl -e'
   for (undef, "0E0", 4) {
      if ($_) {
         printf "Success: %d rows affected\n", $_;
      } else {
         print "Error!\n";
      }
   }
'
Error!
Success: 0 rows affected
Success: 4 rows affected

If 0 was returned on success when no records are affected, you'd be forced to check errors using defined, which is far less convenient than testing for truth (e.g. foo() or die;).

Other true zeroes. (Ignore "0x0"; it warns.)


Need Your Help

Set dimensions for UIImagePickerController "move and scale" cropbox

ios cocoa-touch ipad uiimagepickercontroller crop

How does the "move and scale screen" determine dimensions for its cropbox?

HTML5 placeholder css padding

css html5 google-chrome webkit css3

I've seen this post already and tried everything I could to change the padding for my placeholder but alas, it seems it just doesn't want to cooperate.