Bug in Ruby Driver OrderedHash implementation

11 views
Skip to first unread message

Les Hill

unread,
Oct 3, 2009, 12:06:31 AM10/3/09
to mongodb-dev
Hi,

While writing yet another Ruby ODM for mongoDB, I ran into a
significant bug in the implementation of OrderedHash. The #each
implementation returns the results of the iteration over the key array
and not the OrderedHash itself. This manifests any time you use the
results of #each or #delete_if (which delegates to #each) -- the
common case being chaining as the AS diff method does below.

The patch (with test) is here:

http://github.com/leshill/mongo-ruby-driver/commit/8bc357934ed27b483cabfcdd138019e1fd192d24

Console session showing the behavior contrasted to a Ruby Hash and
ActiveSupport's OrderedHash

>> hash = Hash.new
=> {}
>> hash['a'] = 1
=> 1
>> hash
=> {"a"=>1}
>> as_ohash = ActiveSupport::OrderedHash.new
=> #<OrderedHash {}>
>> as_ohash['b'] = 2
=> 2
>> as_ohash
=> #<OrderedHash {"b"=>2}>
>> hash.diff(as_ohash)
=> {"a"=>1, "b"=>2}
>> as_ohash.diff(hash)
=> #<OrderedHash {"a"=>1, "b"=>2}>
>> id = db.collection('tester').save(hash)
=> #<Mongo::ObjectID:0x17b14c4 @data=[74, 198, 202, 247, 37, 87, 171,
54, 139, 0, 0, 2]>
>> m_ohash = db.collection('tester').find(hash).next_object
=> {"_id"=>#<Mongo::ObjectID:0x17aa7f0 @data=[74, 198, 202, 247, 37,
87, 171, 54, 139, 0, 0, 2]>, "a"=>1}
>> m_ohash.class
=> OrderedHash
>> hash.diff(m_ohash)
TypeError: can't convert Array into Hash
from /usr/local/lib/ruby/gems/1.8/gems/activesupport-2.3.4/lib/
active_support/core_ext/hash/diff.rb:14:in `merge'
from /usr/local/lib/ruby/gems/1.8/gems/activesupport-2.3.4/lib/
active_support/core_ext/hash/diff.rb:14:in `diff'
from (irb):34
>> m_ohash.diff(hash)
NoMethodError: undefined method `merge' for ["_id"]:Array
from /usr/local/lib/ruby/gems/1.8/gems/activesupport-2.3.4/lib/
active_support/core_ext/hash/diff.rb:14:in `diff'
from (irb):35

Les Hill
les...@gmail.com

Michael Dirolf

unread,
Oct 5, 2009, 10:04:45 AM10/5/09
to mongo...@googlegroups.com
Thanks for the heads up! Your patch has been applied in master.

- Mike
Reply all
Reply to author
Forward
0 new messages