Missing roundtrip methods
chocolateboy opened this issue · 3 comments
Several Hash methods in Ruby's standard library return a hash. As expected, many of these methods roundtrip in the same way when called on hashes with Hashie extensions i.e. they return a hash with the same type and behavior as the receiver.
class HashieTest < Hash
include Hashie::Extensions::IndifferentAccess
include Hashie::Extensions::MergeInitializer
end
puts HashieTest.new(foo: "bar").merge(baz: "quux").class # => HashieTest
puts HashieTest.new(foo: "bar").clear.class # => HashieTest
puts HashieTest.new(foo: "bar").replace({}).class # => HashieTest
But I've just noticed that slice
doesn't behave in this way e.g.:
puts HashieTest.new(foo: "bar").slice(:foo).class # => Hash
And in fact there are several methods which return a plain Hash rather than an extended Hash:
- compact
- invert
- reject
- select
- slice
- transform_keys
- transform_values
- update
Makes sense, please PR!
This is due to Hash#slice
being implemented in C, specifically that it creates the new hash with the C function rb_hash_new()
or rb_hash_new_with_size()
. Please see my talk at RubyConf 2018 for more information as to why this happens.
It's not clear how we could handle this. In this specific case, with Hash#slice
, we could override the method to make sure the new Hash is of the same singleton class as the generator, but I'm not really sure what that would look like. Would every extension have to implement #slice
in the same way? That's the only thing I can think of.
Closed via #481