Skip to content

Commit dd6d129

Browse files
corsonknowlesbbatsov
authored andcommitted
Add entry for No Mutable Defaults
Avoid the use of shared mutable objects as hash default values. Complements: rubocop/rubocop#13463 Up
1 parent c72e8dc commit dd6d129

File tree

1 file changed

+39
-0
lines changed

1 file changed

+39
-0
lines changed

README.adoc

+39
Original file line numberDiff line numberDiff line change
@@ -4294,6 +4294,45 @@ hash = { one: 1, two: 2, three: 3 }
42944294

42954295
Avoid the use of mutable objects as hash keys.
42964296

4297+
=== No Mutable Defaults [[no-mutable-defaults]]
4298+
4299+
Avoid the use of shared mutable objects as hash default values.
4300+
4301+
Creating a Hash in such a way will share the default value
4302+
across all keys, causing unexpected behavior when modifying it.
4303+
4304+
For example, when the Hash was created with an Array as the argument,
4305+
calling `hash[:foo] << 'bar'` will also change the value of all
4306+
other keys that have not been explicitly assigned to.
4307+
4308+
[source,ruby]
4309+
----
4310+
# bad
4311+
Hash.new([])
4312+
Hash.new({})
4313+
Hash.new(Array.new)
4314+
Hash.new(Hash.new)
4315+
4316+
# okay -- beware this will silently discard mutations and only remember assignments
4317+
Hash.new { Array.new }
4318+
Hash.new { Hash.new }
4319+
Hash.new { {} }
4320+
Hash.new { [] }
4321+
4322+
# good - frozen solution will raise an error when mutation is attempted
4323+
Hash.new([].freeze)
4324+
Hash.new({}.freeze)
4325+
4326+
# good - using a proc will create a new object for each key
4327+
h = Hash.new
4328+
h.default_proc = ->(h, k) { [] }
4329+
h.default_proc = ->(h, k) { {} }
4330+
4331+
# good - using a block will create a new object for each key
4332+
Hash.new { |h, k| h[k] = [] }
4333+
Hash.new { |h, k| h[k] = {} }
4334+
----
4335+
42974336
=== Hash Literals [[hash-literals]]
42984337

42994338
Use the Ruby 1.9 hash literal syntax when your hash keys are symbols.

0 commit comments

Comments
 (0)