2012-05-02 6 views
0

私はRhodesモバイルアプリケーションフレームワークのRubyを今すぐ学んでいます。この問題は、RhodesのHTTPクライアントがRubyデータ構造にJSON応答を解析することで発生します。なぜですか?key.hash!= 'key'.hashをRubyで使用しますか?

puts @params # prints {"body"=>{"results"=>[]}} 

キー「体」はここに文字列ですので、私の最初の試み@params[:body]は(nilで)失敗し、代わりにそれは@params['body']でなければなりません。私はこれが最も不幸であると感じます。

文字列とシンボルのハッシュが異なる理由、つまりこの場合は:body.hash != 'body'.hashを誰かが説明できますか?

+7

これは異なるオブジェクトであるためです:) –

答えて

6

記号や文字列は、二つの異なる目的を果たします。

文字列は、おなじみのおなじみの友達です。変更可能でガベージコレクト可能です。文字列リテラルまたは#to_sメソッドを使用するたびに、新しい文字列が作成されます。文字列を使用してHTMLマークアップを作成し、画面にテキストなどを出力します。

シンボルは、異なっています。各シンボルは1つのインスタンスにのみ存在し、常に存在します(つまり、ガベージコレクションされません)。そのため、新しいシンボルを非常に慎重に作成する必要があります(String#to_sym:''リテラル)。これらのプロパティは、という名前のの候補になります。たとえば、attr_reader :fooのようなマクロでシンボルを使用するのは慣用的です。

ハッシュを外部ソースから取得した場合(たとえばJSON応答を非直列化した場合)、シンボルを使用してその要素にアクセスする場合は、HashWithIndifferentAccess(他のものが指摘するように)を使用するか、ヘルパーactivesupportのから方法:それは唯一のトップレベルに触れますと子ハッシュに入らないことを

require 'active_support/core_ext' 

h = {"body"=>{"results"=>[]}} 
h.symbolize_keys # => {:body=>{"results"=>[]}} 
h.stringify_keys # => {"body"=>{"results"=>[]}} 

注意。

2

Railsでは、paramsハッシュは実際には標準のruby HashオブジェクトではなくHashWithIndifferentAccessです。これにより、 'action'のような文字列や、actionのようなシンボルを使用して内容にアクセスすることができます。

使用するものにかかわらず同じ結果が得られますが、これはHashWithIndifferentAccessオブジェクトでのみ機能することに注意してください。コピー

Params hash keys as symbols vs strings

+1

コメントにこのリンクを投稿してください。投稿のコピー貼り付けが悪い –

+2

実際に私はちょうどコメント権限を持っています...次回から気を配ります...ありがとうSergio – swati

4

記号や文字列は決して==ません:(非常に合理的な)設計上の決定をだ

:foo == 'foo' # => false 

:foo.eql? 'foo' # => false 

2つのオブジェクトこと:結局のところ、彼らはそのため...

を異なるクラス、メソッド、一方が他方ではない可変である、などを持って、彼らがeql?ことはありませんということは必須ですeql?には通常同じハッシュがありませんが、ハッシュ検索ではhashを使用してからeql?を使用します。だからあなたの質問は本当に "なぜシンボルと文字列ではないeql?"でした。

Railsは、文字列や記号で無関係にアクセスするHashWithIndifferentAccessを使用します。

+0

これは同じ質問に沸きます、なぜ彼らは等しくないでしょうか?彼らはほとんど同じ目的のために使用されていないのですか? – AndiDog

+0

名前付きのパラメータと辞書のキーにのみ使用されるシンボルはありませんか?はいの場合、それぞれの文字列と同じハッシュを持つことができます。シンボルが使用される他の場所は何ですか? – AndiDog

+0

@AndiDog:問題を解決するよりもはるかに多くの混乱を招くでしょう。混乱は悪いです。あなたの「問題」は簡単に解決できます。 –

関連する問題