6

私のフォームはPOSTを介してデータを受け取ります。私がそうするとき、私puts paramsは見ることができます:

{"id" => "123", "id2" => "456"}

今コマンド:

puts params['id']    # =>  123
puts params[:id]     # =>  123

params['id'] = '999'
puts params          # => {"id" => "999", "id2" => "456"}

しかし、私がそうするとき:

params[:id] = '888'
puts params

私は得る

{"id" => "999", "id2" => "456", :id => "888"}

IRBでは正常に機能します。

params
# => {"id2"=>"2", "id"=>"1"}

params[:id]
# => nil

params['id']
# => "1"

を使用して値を読み取ることができるのに:id、それを使用して値を設定できないのはなぜですか?

4

1 に答える 1

12

Rubyのハッシュを使用すると、任意のオブジェクトをキーとして使用できます。文字列(eg "id")と記号(eg :id)は別々のタイプのオブジェクトであるため、ハッシュは、競合することなく同じ視覚的内容を持つ文字列と記号の両方をキーとして持つことができます。

irb(main):001:0> { :a=>1, "a"=>2 }
#=> {:a=>1, "a"=>2}

これは、オブジェクトのキーが常に文字列であるJavaScriptとは明らかに異なります。

Webパラメーター(GETまたはPOST経由)は常に文字列であるため、Sinatraには、記号を使用してパラメーターを要求できる「便利な機能」があり、関連する値を探す前にパラメーターを文字列に変換します。これは、to_s存在しない値を探すときに呼び出すカスタムdefault_procを使用して行われます。

現在の実装は次のとおりです。

def indifferent_hash
  Hash.new {|hash,key| hash[key.to_s] if Symbol === key }
end

ただし、メソッドのカスタム実装は提供されないため[]=(key, val)、文字列の代わりに記号を設定できます。

于 2012-04-30T21:32:16.787 に答える