summaryrefslogtreecommitdiff
path: root/README.md
diff options
context:
space:
mode:
authorMichael Herold <michael.j.herold@gmail.com>2018-02-06 20:31:39 -0600
committerMichael Herold <michael.j.herold@gmail.com>2018-02-06 20:31:39 -0600
commit55c15e0dd5bc242c90728d1d20b334fec4f75c7a (patch)
treec830982cffed9897c0e1d365441584534daad27c /README.md
parent3c6149cdd72ab8cc87cf008cc222514e30ef7470 (diff)
downloadhashie-55c15e0dd5bc242c90728d1d20b334fec4f75c7a.tar.gz
Document Dash double-splat operator gotchas
Let this be a lesson, folks: don't subclass the Hash class! For more information, see the following: https://github.com/intridea/hashie/issues/353#issuecomment-363294886
Diffstat (limited to 'README.md')
-rw-r--r--README.md32
1 files changed, 32 insertions, 0 deletions
diff --git a/README.md b/README.md
index 60162b0..784b73b 100644
--- a/README.md
+++ b/README.md
@@ -695,6 +695,38 @@ p = Tricky.new('trick' => 'two')
p.trick # => NoMethodError
```
+### Potential gotchas
+
+Because Dashes are subclasses of the built-in Ruby Hash class, the double-splat operator takes the Dash as-is without any conversion. This can lead to strange behavior when you use the double-splat operator on a Dash as the first part of a keyword list or built Hash. For example:
+
+```ruby
+class Foo < Hashie::Dash
+ property :bar
+end
+
+foo = Foo.new(bar: 'baz') #=> {:bar=>"baz"}
+qux = { **foo, quux: 'corge' } #=> {:bar=> "baz", :quux=>"corge"}
+qux.is_a?(Foo) #=> true
+qux[:quux]
+#=> raise NoMethodError, "The property 'quux' is not defined for Foo."
+qux.key?(:quux) #=> true
+```
+
+You can work around this problem in two ways:
+
+1. Call `#to_h` on the resulting object to convert it into a Hash.
+2. Use the double-splat operator on the Dash as the last argument in the Hash literal. This will cause the resulting object to be a Hash instead of a Dash, thereby circumventing the problem.
+
+```ruby
+qux = { **foo, quux: 'corge' }.to_h #=> {:bar=> "baz", :quux=>"corge"}
+qux.is_a?(Hash) #=> true
+qux[:quux] #=> "corge"
+
+qux = { quux: 'corge', **foo } #=> {:quux=>"corge", :bar=> "baz"}
+qux.is_a?(Hash) #=> true
+qux[:quux] #=> "corge"
+```
+
### Dash Extension: PropertyTranslation
The `Hashie::Extensions::Dash::PropertyTranslation` mixin extends a Dash with