Skip to content

Commit d98e52b

Browse files
Protect against Ruby Hash regression
1 parent 17b63a9 commit d98e52b

File tree

2 files changed

+27
-12
lines changed

2 files changed

+27
-12
lines changed

lib/bson/ordered_hash.rb

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,16 @@ def extractable_options?
4141
instance_of?(BSON::OrderedHash)
4242
end
4343

44+
def reject(&block)
45+
return to_enum(:reject) unless block_given?
46+
dup.tap {|hash| hash.reject!(&block)}
47+
end
48+
49+
def select(&block)
50+
return to_enum(:select) unless block_given?
51+
dup.tap {|hash| hash.reject!{|k, v| ! yield k,v}}
52+
end
53+
4454
# We only need the body of this class if the RUBY_VERSION is before 1.9
4555
if RUBY_VERSION < '1.9'
4656
attr_accessor :ordered_keys
@@ -142,21 +152,16 @@ def delete_if(&block)
142152
self
143153
end
144154

145-
def reject(&block)
146-
clone = self.clone
147-
return clone unless block_given?
148-
clone.delete_if(&block)
149-
end
150-
151155
def reject!(&block)
152-
changed = false
153-
self.each do |k,v|
154-
if yield k, v
155-
changed = true
156-
delete(k)
156+
return to_enum(:reject!) unless block_given?
157+
raise "can't modify frozen BSON::OrderedHash" if frozen?
158+
keys = @ordered_keys.dup
159+
@ordered_keys.each do |k|
160+
if yield k, self[k]
161+
keys.delete(k)
157162
end
158163
end
159-
changed ? self : nil
164+
keys == @ordered_keys ? nil : @ordered_keys = keys
160165
end
161166

162167
def clear

lib/bson/support/hash_with_indifferent_access.rb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,16 @@ def self.new_from_hash_copying_default(hash)
4949
end
5050
end
5151

52+
def reject(&block)
53+
return to_enum(:reject) unless block_given?
54+
dup.tap {|hash| hash.reject!(&block)}
55+
end
56+
57+
def select(&block)
58+
return to_enum(:select) unless block_given?
59+
dup.tap {|hash| hash.reject!{|k, v| ! yield k, v}}
60+
end
61+
5262
alias_method :regular_writer, :[]= unless method_defined?(:regular_writer)
5363
alias_method :regular_update, :update unless method_defined?(:regular_update)
5464

0 commit comments

Comments
 (0)