当你要求一个数组时,Ruby的dbi select_all给出了有趣的结果

时间:2012-06-16 01:37:55

标签: mysql ruby

考虑这个程序

require 'dbi'

handle = DBI.connect('DBI:Mysql:tasks', 'root', 'stupid')

handle.select_all('select * from tasks') do |row|
  puts row.inspect
end

rows = handle.select_all('select * from tasks')
puts rows.inspect

第一次调用select_all传递一个块,它用来遍历表行,就像它想象的那样。这是迭代的标准Ruby习语,所以它当然有效。

第二个调用应该返回相同的数据,但是一次性打包,打包在一个数组中。数组实际包含的是表格的最后一行一遍又一遍!

这是一个错误,还是我做错了什么?

2 个答案:

答案 0 :(得分:1)

我也偶然发现了这一点。经过大量研究后,我决定与特定语句手相关的每个DBI::Row实例引用相同的内存。更糟糕的仍然是复制或克隆它没有任何区别。获得正确副本的唯一方法是将其转换为.to_a的数组,这意味着您将失去方法:(

我煞费苦心地提交了一份关于rubyforge的错误报告 - 不是因为我认为它会得到修复,而是因为它可能会帮助其他一些扯掉头发的傻瓜。

答案 1 :(得分:0)

我也偶然发现了这一点。经过大量研究后,我决定与特定语句关联的每个DBI :: Row实例都引用相同的内存。更糟糕的仍然是复制或克隆它没有任何区别。获得正确副本的唯一方法是将其转换为带有.to_a的数组,这意味着您放弃了方法:(

我煞费苦心地提交了一份关于rubyforge的错误报告 - 不是因为我认为它会得到修复,而是因为它可能会帮助其他一些扯掉头发的傻瓜。

事实上,我刚刚将几个脚本转换为DBI的Sequel。续集看起来非常好,因为它允许ORM类型访问以及支持像dbi这样的原始sql。

翻译很直接。