I am querying a database using DBI and ODBC. After I run the execute, I
want to grab each row as an array, and add it to another array,
essentially
creating an Array of Arrays. I've tried this two ways with the same
result:
sth = dbh.execute("SELECT * FROM SOMETABLE")
rows = sth.fetch_all
and
rows = sth.fetch do |row|
rows << row
end
The result for both is that the last row is repeated in the array
however
many times there are rows. Why isn't it appending correctly?
Thanks,
Anthony
on 2012-02-07 22:28
on 2012-02-07 23:05
On Tue, Feb 7, 2012 at 10:27 PM, Anthony Simonelli <asimonelli01@gmail.com> wrote: > rows << row > end > > The result for both is that the last row is repeated in the array however > many times there are rows. Why isn't it appending correctly? Probably because the DB driver optimizes object allocation and reuses the same instance. Then this is what happens: irb(main):006:0> rows = [] => [] irb(main):007:0> a = %w{a b c d} => ["a", "b", "c", "d"] irb(main):008:0> rows << a => [["a", "b", "c", "d"]] irb(main):009:0> a[2] = 99 => 99 irb(main):010:0> rows << a => [["a", "b", 99, "d"], ["a", "b", 99, "d"]] The phenomenon is called "aliasing". You can solve it by copying row Arrays. rows = [] sth.fetch do |row| rows << row.to_a # if rows is not an Array rows << row.dup # if rows is an Array end Kind regards robert
on 2012-02-07 23:23
On Tue, Feb 7, 2012 at 11:04 PM, Robert Klemme <shortcutter@googlemail.com>wrote: > > > the same instance. Then this is what happens: > => [["a", "b", 99, "d"], ["a", "b", 99, "d"]] > end > Would `Array(row)` not be a clean implementation of this ? peterv@ASUS:~$ irb 001:0> row = "a string" => "a string" 002:0> Array(row) => ["a string"] 003:0> row = [:array_entry] => [:array_entry] 004:0> Array(row) => [:array_entry] Peter
on 2012-02-08 09:52
On Tue, Feb 7, 2012 at 11:22 PM, Peter Vandenabeele <peter@vandenabeele.com> wrote: >> > >> > many times there are rows. Why isn't it appending correctly? >> irb(main):009:0> a[2] = 99 >> sth.fetch do |row| > 002:0> Array(row) > => ["a string"] > 003:0> row = [:array_entry] > => [:array_entry] > 004:0> Array(row) > => [:array_entry] Judge for yourself: irb(main):001:0> a = [:x] => [:x] irb(main):002:0> b = Array(a) => [:x] irb(main):003:0> b.equal? a => true irb(main):004:0> a.object_id == b.object_id => true Kind regards robert
Please log in before posting. Registration is free and takes only a minute.
Existing account
(Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
Log in with Google account | Log in with Yahoo account
No account? Register here.