使用Symbol vs String作为params散列中的键的Rails

Sub*_*dra 8 ruby hash ruby-on-rails

如果我们使用字符串作为哈希键,Ruby需要评估字符串并查看其内容(并计算其上的哈希函数)并将结果与​​已存储在哈希中的键的(哈希)值进行比较.

如果我们使用一个符号作为Hash键,它隐含着它是不可变的,所以Ruby基本上只是将object-id的(哈希函数)与已经存储在其中的键的(哈希)对象-id进行比较.哈希.(快多了).

但事情是在Rails params中的实例HashWithIndifferentAccess,如果我们写params[:some_key]它转换:some_key'some_key'然后它试图寻找params散列中的键. 第159行

 def convert_key(key)
    key.kind_of?(Symbol) ? key.to_s : key
  end
Run Code Online (Sandbox Code Playgroud)

因此,如果在Hash HashWithIndifferentAccess中将String作为键,查找速度很慢,为什么将符号键转换为字符串.

Gre*_*vis 7

原因之一是安全性.它在Ruby 2.2或更高版本中已不再适用.

在Ruby 2.2符号没有被垃圾收集之前.这意味着一旦通过文字(:my_symbol)创建符号,#to_sym它就会永远存在.

如果Rails使用符号而不是字符串,那么它将创建与请求中的params名称相对应的符号.攻击者可以通过使应用程序分配数十万个符号来发送带有params命名param1,param2...和耗尽服务器内存的请求.

在Ruby 2.2或更高版本中不再是这种情况