From: Brian C. <B.C...@po...> - 2003-08-05 14:11:58
|
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: 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. |