Brad Fitzpatrick (bradfitz) wrote in lj_dev,
Brad Fitzpatrick
bradfitz
lj_dev

Potential DBI change

If you don't already know, DBI's behavior is different between fetchrow_arrayref and fetchrow_hashref.

Fetching arrayrefs always returns the same arrayref pointer, just with the values changed. So you can't do this:

# BAD CODE
push @items, $_ while $_ = $sth->fetchrow_arrayref;

Because each $_ will be the same, until the final undef.

But you can do that with hashrefs:

# Currently okay code:
push @items, $_ while $_ = $sth->fetchrow_hashref;

And we do that all over LJ code. However, I recently noted this in the DBI docs:

"fetchrow_hashref"
Currently, a new hash reference is returned for each row. This
will change in the future to return the same hash ref each time, so
don't rely on the current behaviour.
So, I think we need to audit our usage of fetchrow_hashref so we're not bitten in the future.

New code should be:

# safe version:
push @items, {%$_} while $_ = $sth->fetchrow_hashref;

But that's kinda lame, since it makes two copies. :-/

In general, try and use fetchrow_arrayref if possible, but don't be passing around arrayrefs over long distances of code and doing stuff later like:

my ($foo, $bar, $baz) = @{$arrayref}[2,4,8];

That just gets insane.
Subscribe
  • Post a new comment

    Error

    Anonymous comments are disabled in this journal

    default userpic

    Your reply will be screened

    Your IP address will be recorded 

  • 4 comments