Advanced Rails - Building Industrial-Strength Web Apps in Record Time

(Tuis.) #1

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').

Free download pdf