2016-05-17 21 views
7

ハッシュキーとして文字列を使用する場合、Rubyはその文字列を評価し、内容を見て(ハッシュ関数を計算して)ハッシュにすでに格納されているキーの値をハッシュします。RailsはSymbolとStringをparamsハッシュのキーとして使用します

ハッシュキーとしてシンボルを使用すると、それは不変であるという暗黙のため、Rubyは基本的にobject-idのハッシュ関数とキーのハッシュされたオブジェクトIDの比較を行います。既にハッシュに格納されています。 (はるかに高速)。

は、しかし、事は、我々はparams[:some_key]を書く場合には'some_key'から:some_keyを変換し、それはparamsハッシュ内のキーを探すためにしようと、HashWithIndifferentAccessのインスタンスであるRailsのparamsです。 line 159

def convert_key(key) 
    key.kind_of?(Symbol) ? key.to_s : key 
    end 

検索はハッシュでキーに文字列で遅いのであれば、なぜHashWithIndifferentAccessは、文字列に記号キーを変換しません。

答えて

3

これはセキュリティの理由です。これはもはやRuby 2.2以降では関係ありません。

前にRuby 2.2のシンボルはガベージコレクションされませんでした。これは、シンボルがリテラル(:my_symbol)またはによって作成されると、それはの周りに永遠にとなることを意味します。

Railsが文字列の代わりにシンボルを使用した場合、要求内のparamsの名前に対応するシンボルが作成されます。攻撃者はparam1param2という名前のパラメータでリクエストを送信し、数百万のシンボルを割り当てることでサーバーのメモリを使い果たす可能性があります。

Ruby 2.2以降ではなくなりました

+0

これはありがとうございます! –

0

:symbol.to_sは常に新しいインスタンス文字列を作成しますが、"string".to_symは常に同じシンボルを生成します。したがって

p "string".to_sym.object_id 
#=> 272028 
p "string".to_sym.object_id 
#=> 272028 

p :symbol.to_sym.to_s.object_id 
#=>70127441809260 
p :symbol.to_sym.to_s.object_id 
#=>70127441809160 

、1つが(それは文字列としてキーを返します)hash.keysメソッドを使用している場合は特に、クラス店のデザイナー文字列としてキーがアクセス中に文字列の不要な作成を避けるためと思われます。

関連する問題