If we use a string as a Hash key, Ruby needs to evaluate the string and look at it's contents (and compute a hash function on that) and compare the result against the (hashed) values of the keys which are already stored in the Hash.
If we use a symbol as a Hash key, it's implicit that it's immutable, so Ruby can basically just do a comparison of the (hash function of the) object-id against the (hashed) object-ids of keys which are already stored in the Hash. (much faster).
But the thing is in Rails params
which is instance of HashWithIndifferentAccess
, if we write params[:some_key]
it converts :some_key
to 'some_key'
and then it tries to look for the key in params hash.
line 159
def convert_key(key)
key.kind_of?(Symbol) ? key.to_s : key
end
so if the lookup is slow with String as key in Hash, why does HashWithIndifferentAccess
converts symbol key to string.
The reason used to be security. It's no longer relevant in Ruby 2.2 or later.
Before Ruby 2.2 symbols were not garbage collected. This means that once a symbol was created via a literal (:my_symbol
) or #to_sym
it would be around forever.
If Rails used symbols instead of strings then it would create symbols corresponding to names of params in a request. An attacker could send requests with params named param1
, param2
, ... and exhaust server memory by making the app allocate hundreds of thousands of symbols.
It's no longer the case in Ruby 2.2 or later
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With