Hash
68 | Chapter 2: ActiveSupport and RailTies
h = {:a => 123, "b" => 456}
h.stringify_keys # => {"a"=>123, "b"=>456}
h.symbolize_keys # => {:a=>123, :b=>456}
- Hash#assert_valid_keys(:key1, ...)raises anArgumentErrorif the hash contains keys
not in the argument list. This is used to ensure that only valid options are provided to
a keyword-argument-based function. - Hash#reverse_mergeandHash#reverse_merge!(in-place) work likeHash#merge, but in
reverse order; in the case of duplicate keys, existing tuples beat those in the argument.
This can be used to provide default arguments to a function.
options = {:a => 3, :c => 5}
options.reverse_merge!(:a => 1, :b => 4)
options # => {:a=>3, :b=>4, :c=>5} - Hash#slicereturns a new hash with only the keys specified. Inversely,Hash#except
returns a new hash excluding the specified keys:
options = {:a => 3, :b => 4, :c => 5}
options.slice(:a, :c) # => {:c=>5, :a=>3}
options.except(:a) # => {:b=>4, :c=>5}
Hash#sliceandHash#exceptalso come in in-place versions, respectively:Hash#slice!
andHash#except!.
HashWithIndifferentAccess core_ext/hash/indifferent_access.rb
AHashWithIndifferentAccessis a hash whose elements can be accessed with either string
or symbol keys:
options = {:a => 3, :b => 4}.with_indifferent_access
options.class # => HashWithIndifferentAccess
options[:a] # => 3
options["a"] = 100
options[:a] # => 100
HashWithIndifferentAccessis primarily used to offer a nice API to users, for example, so
that a developer can write params[:user]or params["user"]. The stringify_keys or
symbolize_keys methods should be used in option processing.
However,HashWithIndifferentAccessalso fixes a class of security exploits in Rails. In Ruby
1.8, symbols are not garbage collected, so aparamshash purely keyed on symbols (as it
used to be) could lead to a denial-of-service attack. A malicious client could leak memory
and exhaust the symbol table by issuing many requests with unique parameter names. Inci-
dentally, Ruby 1.9 will obviate the need forHashWithIndifferentAccess, because symbols
and strings will be treated identically (:aoeu == 'aoeu').