Brad Fitzpatrick (bradfitz) wrote in lj_dev,
Brad Fitzpatrick

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:

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:

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.

  • Post a new comment


    Anonymous comments are disabled in this journal

    default userpic

    Your reply will be screened

    Your IP address will be recorded