# frozen_string_literal: trueclassHash# Returns a new hash with all keys converted to strings.## hash = { name: 'Rob', age: '28' }## hash.stringify_keys# # => {"name"=>"Rob", "age"=>"28"}defstringify_keystransform_keys(&:to_s)end# Destructively converts all keys to strings. Same as# +stringify_keys+, but modifies +self+.defstringify_keys!transform_keys!(&:to_s)end# Returns a new hash with all keys converted to symbols, as long as# they respond to +to_sym+.## hash = { 'name' => 'Rob', 'age' => '28' }## hash.symbolize_keys# # => {:name=>"Rob", :age=>"28"}defsymbolize_keystransform_keys{|key|key.to_symrescuekey}endalias_method:to_options,:symbolize_keys# Destructively converts all keys to symbols, as long as they respond# to +to_sym+. Same as +symbolize_keys+, but modifies +self+.defsymbolize_keys!transform_keys!{|key|key.to_symrescuekey}endalias_method:to_options!,:symbolize_keys!# Validates all keys in a hash match <tt>*valid_keys</tt>, raising# +ArgumentError+ on a mismatch.## Note that keys are treated differently than HashWithIndifferentAccess,# meaning that string and symbol keys will not match.## { name: 'Rob', years: '28' }.assert_valid_keys(:name, :age) # => raises "ArgumentError: Unknown key: :years. Valid keys are: :name, :age"# { name: 'Rob', age: '28' }.assert_valid_keys('name', 'age') # => raises "ArgumentError: Unknown key: :name. Valid keys are: 'name', 'age'"# { name: 'Rob', age: '28' }.assert_valid_keys(:name, :age) # => passes, raises nothingdefassert_valid_keys(*valid_keys)valid_keys.flatten!each_keydo|k|unlessvalid_keys.include?(k)raiseArgumentError.new("Unknown key: #{k.inspect}. Valid keys are: #{valid_keys.map(&:inspect).join(', ')}")endendend# Returns a new hash with all keys converted by the block operation.# This includes the keys from the root hash and from all# nested hashes and arrays.## hash = { person: { name: 'Rob', age: '28' } }## hash.deep_transform_keys{ |key| key.to_s.upcase }# # => {"PERSON"=>{"NAME"=>"Rob", "AGE"=>"28"}}defdeep_transform_keys(&block)_deep_transform_keys_in_object(self,&block)end# Destructively converts all keys by using the block operation.# This includes the keys from the root hash and from all# nested hashes and arrays.defdeep_transform_keys!(&block)_deep_transform_keys_in_object!(self,&block)end# Returns a new hash with all keys converted to strings.# This includes the keys from the root hash and from all# nested hashes and arrays.## hash = { person: { name: 'Rob', age: '28' } }## hash.deep_stringify_keys# # => {"person"=>{"name"=>"Rob", "age"=>"28"}}defdeep_stringify_keysdeep_transform_keys(&:to_s)end# Destructively converts all keys to strings.# This includes the keys from the root hash and from all# nested hashes and arrays.defdeep_stringify_keys!deep_transform_keys!(&:to_s)end# Returns a new hash with all keys converted to symbols, as long as# they respond to +to_sym+. This includes the keys from the root hash# and from all nested hashes and arrays.## hash = { 'person' => { 'name' => 'Rob', 'age' => '28' } }## hash.deep_symbolize_keys# # => {:person=>{:name=>"Rob", :age=>"28"}}defdeep_symbolize_keysdeep_transform_keys{|key|key.to_symrescuekey}end# Destructively converts all keys to symbols, as long as they respond# to +to_sym+. This includes the keys from the root hash and from all# nested hashes and arrays.defdeep_symbolize_keys!deep_transform_keys!{|key|key.to_symrescuekey}endprivate# Support methods for deep transforming nested hashes and arrays.def_deep_transform_keys_in_object(object,&block)caseobjectwhenHashobject.each_with_object(self.class.new)do|(key,value),result|result[yield(key)]=_deep_transform_keys_in_object(value,&block)endwhenArrayobject.map{|e|_deep_transform_keys_in_object(e,&block)}elseobjectendenddef_deep_transform_keys_in_object!(object,&block)caseobjectwhenHashobject.keys.eachdo|key|value=object.delete(key)object[yield(key)]=_deep_transform_keys_in_object!(value,&block)endobjectwhenArrayobject.map!{|e|_deep_transform_keys_in_object!(e,&block)}elseobjectendendend