Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 为什么Rails'`HashWithInferenceTaccess`将键存储为字符串而不是符号?_Ruby On Rails_Ruby_Hashmap_Activesupport - Fatal编程技术网

Ruby on rails 为什么Rails'`HashWithInferenceTaccess`将键存储为字符串而不是符号?

Ruby on rails 为什么Rails'`HashWithInferenceTaccess`将键存储为字符串而不是符号?,ruby-on-rails,ruby,hashmap,activesupport,Ruby On Rails,Ruby,Hashmap,Activesupport,我使用enum将数据库中的整数映射到ruby代码中的语义值,但是我注意到它使用的键是字符串。当我检查散列的类型时,我发现它是一个ActiveSupport::HashWithInferenceTaccess,而不是一个标准的hash,这是有意义的,但会导致一个问题,为什么Rails选择在内部以字符串而不是符号的形式存储和比较值 各国: 在整个写入接口中用作键时,内部符号映射到字符串 符号通常用于哈希,因为它们比较快,但Rails选择使用字符串。他们为什么选择这样做,绩效差异有多大 他们为什么选择

我使用
enum
将数据库中的整数映射到ruby代码中的语义值,但是我注意到它使用的键是字符串。当我检查散列的类型时,我发现它是一个
ActiveSupport::HashWithInferenceTaccess
,而不是一个标准的
hash
,这是有意义的,但会导致一个问题,为什么Rails选择在内部以字符串而不是符号的形式存储和比较值

各国:

在整个写入接口中用作键时,内部符号映射到字符串

符号通常用于哈希,因为它们比较快,但Rails选择使用字符串。他们为什么选择这样做,绩效差异有多大

他们为什么选择这样做

ActiveSupport::HashWithIndifferentAccess
主要用于处理来自外部的参数。符号存储在ruby堆中,通常不会释放回系统

在从外部获取密钥的东西中使用符号作为密钥,会导致针对
OutOfMemory
攻击的漏洞(
[D]DoS
,发送带有随机生成的参数名称的查询)。这就是为什么选择字符串,AFAIU。要获得100%的保证,请咨询DHH

性能上的差异有多大


用于检查。该网站不应该是“请为我做基准测试”网站。

过去,有些实现无法收集符号。IOW,一个符号一旦创建,将一直保留在内存中,直到进程结束(对于Rails应用程序这样的服务器进程,可能需要几个月)。直到三周前,最流行的实现YARV碰巧就是其中之一

因此,您可以通过生成大量符号来DoS运行这些易受攻击的实现之一的Ruby系统,并且由于Rails使用HWIA作为请求参数(这些参数完全在攻击者的控制之下),除其他外,这样做非常简单


现在,每个实现都支持收集符号(JRuby和Rubinius几年前就支持了它,YARV从2.4.0开始就支持它),这个实现策略可能会改变……或者不会:永远不要改变正在运行的系统。

Btw符号现在在Ruby 2.4.0中被GCed。@ndn除非它们的长度大于或等于24字节,它们存储在
RValue
s中,而不是GC'ed。谷歌搜索“ruby堆”。也许ruby 2.4也改变了这一点,但我对此表示怀疑。