2011-12-23 58 views
7

在Sinatra中,我使用params来获取通过URL查询字符串传递的键/值。我注意到我可以使用字符串或符号作为获取值的关键。因此,如果网址是:如何使用符号访问Sinatra params?

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为一个Hash。但是这似乎并不是哈希的常见行为。

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 

随着评论的状态,它的这种方法(调用同一文件的line 704),允许在params哈希字符串和符号的访问。

+1

我不知道这是否可能与红宝石,但如果他们可以重写哈希访问方法('[]'),是不是更好,允许此方法将符号转换为字符串,而不是重复每对?看起来像是一个相对昂贵的设计选择,它给了它什么好处。 – MarioDS

+0

[当前实现](https://github.com/sinatra/sinatra/blob/6ce8a94005397695f0fd2cc241cd09fb325dd567/lib/sinatra/base.rb#L1060-L1062)要轻得多:'Hash.new {| hash,key | hash [key.to_s] if Symbol === key}',这意味着如果密钥是符号,请尝试密钥的字符串版本。 –