0

Rhodesモバイルアプリケーションフレームワークについて現在Rubyを学習していて、この問題に遭遇しました。RhodesのHTTPクライアントはJSON応答をRubyデータ構造に解析します。

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

ここではキー「body」が文字列であるため、最初の試行@params[:body]は失敗し(is nil)、代わりに。である必要があります@params['body']。これは最も残念なことです。

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

4

3 に答える 3

6

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

文字列は古き良きおなじみの友達です。変更可能でゴミ収集可能です。文字列リテラルまたはメソッドを使用するたび#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"=>[]}}

トップレベルにのみ触れ、子ハッシュには入らないことに注意してください。

于 2012-05-02T14:03:45.240 に答える
4

記号と文字列は決してありません==

:foo == 'foo'  # => false

これは(非常に合理的な)設計上の決定です。結局のところ、それらには異なるクラス、メソッドがあり、一方は変更可能で、もう一方は変更可能ではありません...

そのため、決してそうではないことが必須ですeql?

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

eql?通常は同じハッシュを持たない2つのオブジェクトですが、同じハッシュを持っている場合でも、ハッシュルックアップはとを使用hash eql?ます。だからあなたの質問は本当に「なぜ記号と文字列はそうではないのかeql?」でした。

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

于 2012-05-02T14:26:38.657 に答える
2

Railsでは、paramsハッシュは実際には標準のruby Hashオブジェクトではなく、HashWithIndifferentAccessです。これにより、「action」のような文字列または:actionのような記号を使用してコンテンツにアクセスできます。

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

コピー元:シンボル対文字列としてのパラメータハッシュキー

于 2012-05-02T14:02:22.137 に答える