Mash's respond_to? and method call do not behave in consistently
davidstosik opened this issue · 1 comments
Here is a simple example:
mash = Hashie::Mash.new(a: 1)
mash.a
#=> 1
mash.b
#=> nil
mash.respond_to?(:b)
#=> false # but I expected true, as I just showed it responds!
This becomes an issue when I use a delegator on a Hashie::Mash
object:
class Foo < SimpleDelegator
def initialize(hash)
super(Hashie::Mash.new(hash))
end
end
# This class can be initiated with a simple hash:
foo = Foo.new(a: 1)
# and will also delegate method calls to the Mash object
foo.a
#=> 1
The problem arises when I try to call an undefined method: foo.b
. Because Mash
is able to respond nil
, I was expecting Foo
to respond the same, but that is not what happens!
# Expected
foo.b
#=> nil
# Actual
foo.b
# NoMethodError: undefined method `b' for #<Hashie::Mash a=1>
For consistency, I would like to suggest either of the following approaches:
1. All method calls fetch from the hash
If mash.b
returns nil
, then mash.respond_to?(:b)
should return true
.
Implementation.
2. Non-existing keys produce undefined methods
If mash.respond_to?(:b)
returns false
, then mash.b
should raise NoMethodError
.
Implementation.
I think I prefer the option 1, but it conflicts with the way log_collision?
is implemented.
Good read: method_missing
, Politely. (And this is a mirror of Polite Programmer talk that article mention.)
I think we would merge anything that doesn't break existing specs. Be wary of side effects!
https://code.dblock.org/2017/02/24/the-demonic-possession-of-hashie-mash.html