2013-04-25 35 views
2

这个问题应该是这一个相反:Why use symbols as hash keys in Ruby?一个为什么要使用字符串键的哈希过的符号

正如你所看到的,大家都认为符号是哈希键是最合理的选择。但是,我正在使用sinatra框架构建Web应用程序,并且request对象是一个散列,其中包含String s作为键。任何人都可以解释为什么这将是一个设计选择?

+1

请注意,使用Sinatra,您可以使用[字符串或符号](http://stackoverflow.com/questions/8619707/accessing-sinatra-params-using-a-symbol)。 – Phrogz 2013-04-25 17:27:49

+2

“每个人都认为符号是散列键最合理的选择”,否,他们不会。这是程序员的选择,有时基于牧群本能,但更多时候是基于当时最有意义的。在字符串和符号之间,我通常使用符号,但我也使用正则表达式模式甚至数组作为我的密钥,因为它是合适的。哈希是一个容器,就像一个数组,可以包含各种各样的东西。我们坚持的内容取决于我们,并且应该适用于该应用程序。如果我们只谈论Sinatra中的参数哈希,那么请参阅@Phrogz答案。 – 2013-04-25 17:50:41

回答

4

因为键的来源 - 查询字符串 - 由字符串组成,因此通过此字符串搜索键,通过字符串对散列进行索引是最直接的方便。

在Ruby运行时中创建的每个Symbol都被分配并且永不释放。通过发送具有唯一查询字符串参数的数十万个请求,可以获得理论(但不太可能)的DOS攻击。如果它们被符号化,每个请求将缓慢增长运行时内存池。

另一方面,字符串可能被垃圾收集。在各种请求中处理的数千个独特字符串最终会消失,并且不会产生长期影响。

编辑:请注意,Sinatra,符号也可访问params哈希值。但是,这是通过创建一个由字符串索引的散列,并在发出请求时将符号(在您的代码中)转换为字符串来完成的。除非你做下面的事情:

params.each{ |key,_| key.to_sym } 

......你没有任何符号伪DOS攻击的风险。

+0

'request'对象比查询字符串保存的要多得多。 HTTP头,一个。由于这些总是相同的,因此在内存消耗方面符号似乎是更合理的选择。另外,Rack在任何地方使用字符串键。 – MarioDS 2013-04-25 17:20:41

+0

你让'params'与'request'混淆我猜? – MarioDS 2013-04-25 17:32:26

+0

@MarioDeSchaepmeester是的,对不起,我以为你在使用Sinatra'params'对象。而不是Rack'request'。 – Phrogz 2013-04-25 17:33:53