My form receives data via POST. When I do puts params I can see:
{"id" => "123", "id2" => "456"}
now the commands:
puts params['id'] # => 123
puts params[:id] # => 123
params['id'] = '999'
puts params # => {"id" => "999", "id2" => "456"}
but when I do:
params[:id] = '888'
puts params
I get
{"id" => "999", "id2" => "456", :id => "888"}
In IRB it works fine:
params
# => {"id2"=>"2", "id"=>"1"}
params[:id]
# => nil
params['id']
# => "1"
Why can I read the value using :id, but not set the value using that?
Hashes in Ruby allow arbitrary objects to be used as keys. As strings (e.g.
"id") and symbols (e.g.:id) are separate types of objects, a hash may have as a key both a string and symbol with the same visual contents without conflict:This is distinctly different from JavaScript, where the keys for objects are always strings.
Because web parameters (whether via GET or POST) are always strings, Sinatra has a ‘convenience’ that allows you to ask for a parameter using a symbol and it will convert it to a string before looking for the associated value. It does this by using a custom default_proc that calls
to_swhen looking for a value that does not exist.Here’s the current implementation:
However, it does not provide a custom implementation for the
[]=(key, val)method, and thus you can set a symbol instead of the string.