OK, rolling back to dbi-0.0.18 didn’t fix this, so I’ve dug around some more.
The following program demonstrates the problem without any database access:
---- 8< ------------------------------------------------------------------
#!/usr/local/bin/ruby
require ‘dbi/row’
res =
r = DBI::Row.new([“col1”,“col2”],[nil,nil])
[[“one”,1],[“two”,2],[“three”,3]].each do |x,y|
r[“col1”] = x
r[“col2”] = y
p r
res << r.dup
end
p res # [[“three”, 3], [“three”, 3], [“three”, 3]] under ruby-1.8.0
---- 8< ------------------------------------------------------------------
Now, looking at the definition of DBI::Row, it is based on delegation to
Array. So I can boil it down to the following:
---- 8< ------------------------------------------------------------------
#!/usr/local/bin/ruby -w
require ‘delegate’
class Foo < DelegateClass(Array) # distilled from DBI::Row
def initialize(arr)
@arr = arr
super(@arr)
end
def clone_with(new_values)
Foo.new(new_values)
end
def clone
clone_with(@arr.dup)
end
end
r = Foo.new([nil,nil])
res =
[[“one”,1],[“two”,2],[“three”,3]].each do |x,y|
r[0] = x
r[1] = y
p r
res << r.dup
end
p res
---- 8< ------------------------------------------------------------------
$ ruby16 -v bug2.rb
ruby 1.6.8 (2002-12-24) [i386-freebsd4.7]
[“one”, 1]
[“two”, 2]
[“three”, 3]
[[“one”, 1], [“two”, 2], [“three”, 3]] <<< expected
$ ruby18 -v bug2.rb
ruby 1.8.0 (2003-08-04) [i386-freebsd4.7]
[“one”, 1]
[“two”, 2]
[“three”, 3]
[[“three”, 3], [“three”, 3], [“three”, 3]] <<< actual under 1.8.0
So, it looks like DBI is depending on some behaviour of delegate, and/or
‘dup’ making use of ‘clone’, which is no longer true in 1.8.0
But I don’t know how to fix this; adding my own ‘dup’ method to class Foo
doesn’t seem to help. Anybody got any ideas?
Thanks,
Brian.
···
On Tue, Aug 05, 2003 at 10:40:06PM +0900, Brian Candler wrote:
The following test program works correctly with ruby-dbi-all-0.0.18 under
ruby-1.6.8, but not ruby-dbi-all-0.0.20 under ruby-1.8.0: