我的表单通过POST接收数据。当我puts params
时,我可以看到:
{"id" => "123", "id2" => "456"}
现在命令:
puts params['id'] # => 123
puts params[:id] # => 123
params['id'] = '999'
puts params # => {"id" => "999", "id2" => "456"}
但是当我这样做时:
params[:id] = '888'
puts params
我得到了
{"id" => "999", "id2" => "456", :id => "888"}
在IRB中它运作良好:
params
# => {"id2"=>"2", "id"=>"1"}
params[:id]
# => nil
params['id']
# => "1"
为什么我可以使用:id
读取值,但不能使用该值设置值?
答案 0 :(得分:12)
Ruby中的哈希允许将任意对象用作键。由于字符串(例如"id"
)和符号(例如:id
)是不同类型的对象,因此散列可以将具有相同视觉内容的字符串和符号作为键而不会发生冲突:
irb(main):001:0> { :a=>1, "a"=>2 }
#=> {:a=>1, "a"=>2}
这与JavaScript明显不同,JavaScript中对象的键始终是字符串。
由于Web参数(无论是通过GET还是POST)始终是字符串,因此Sinatra具有“便利性”,允许您使用符号请求参数,并在查找关联值之前将其转换为字符串。它通过使用在查找不存在的值时调用to_s
的自定义default_proc来实现此目的。
def indifferent_hash
Hash.new {|hash,key| hash[key.to_s] if Symbol === key }
end
但是,它没有为[]=(key, val)
方法提供自定义实现,因此您可以设置符号而不是字符串。