2011-12-23 8 views
7

Sinatraでは、私はURLクエリ文字列を渡されたキー/値を取得するためにparamsを使用します。私は値を得るためにキーとして文字列かシンボルのどちらかを使うことができることに気づいた。だから、URLがある場合:次にシンボルを使用してSinatraのパラメータにアクセスするにはどうすればよいですか?

http://localhost:4567/x?a=1&b=2 

params[:a] # => "1" 
params["a"] # => "1" 
params.to_s # => '{"name"=>"x", "a"=>"1", "b"=>"2"}' 
params.class # => Hash 

私はのparamsを伝えることができますが、ハッシュです。しかし、これはハッシュの共通の行動ではないようです。

h = {"a" => "1", "b" => "2"} 
h["a"] # => "1" 
h[:a] # => nil 

これがSinatraを通じてどのように達成されたか説明してください。

答えて

16

sourceの読んだりすることをお勧めします。具体的には、indifferent_params method。コメントの状態として

# Enable string or symbol key access to the nested params hash. 
def indifferent_params(params) 
    params = indifferent_hash.merge(params) 
    params.each do |key, value| 
    next unless value.is_a?(Hash) 
    params[key] = indifferent_params(value) 
    end 
end 

、それはparamsハッシュへの文字列とシンボルのアクセスを許可します(同じファイルのline 704に呼び出された)この方法です。

+1

これはrubyで可能かどうか分かりませんが、ハッシュアクセスメソッド( '[]')をオーバーライドできる場合は、このメソッドがシンボルを文字列に変換するのではなく、ペア?それがもたらす利益のために比較的高価な設計の選択のようです。 – MarioDS

+0

[現在の実装](https://github.com/sinatra/sinatra/blob/6ce8a94005397695f0fd2cc241cd09fb325dd567/lib/sinatra/base.rb#L1060-L1062)ははるかに軽いです: 'Hash.new {| hash、key |ハッシュ[key.to_s] if Symbol === key} '、つまりキーがシンボルの場合は、キーのStringバージョンで試してください。 –