Sinatra:params hash无法合并

时间:2016-06-17 15:15:53

标签: ruby sinatra

我想将哈希与默认参数和请求中给出的实际参数合并。当我称这个看似无辜的剧本时:

#!/usr/bin/env ruby

require 'sinatra'

get '/' do
        defaults = { 'p1' => 'default1', 'p2' => 'default2' }
        # params = request.params
        params = defaults.merge(params)
        params
end

curl http://localhost:4567?p0=request然后它与

崩溃
Listening on localhost:4567, CTRL+C to stop
2016-06-17 11:10:34 - TypeError - no implicit conversion of nil into Hash:
        sinatrabug:8:in `merge'
        sinatrabug:8:in `block in <main>'

当我直接访问Rack request.params时,它可以正常工作。我查看了Sinatra的来源,但我无法理解。

所以我有一个解决我实际问题的方法。但我不知道为什么它有效。

我的问题是:为什么我可以将param分配给参数,为什么类Hash但在defaults.merge params中它会引发异常?

有什么想法吗?

3 个答案:

答案 0 :(得分:1)

当您拨打此电话params时,您的代码会抛出错误,因为nildefaults.merge(params)。我假设您尝试将defaultsrequest.params合并,其中应包含GET中的参数。

更改此行

params = defaults.merge(params)

到这个

params = defaults.merge(request.params)

答案 1 :(得分:1)

这是由Ruby处理局部变量和setter方法(即以=结尾的方法)具有相同名称的方式引起的。当Ruby到达行

params = defaults.merge(params)

它假设您要创建名为params的新局部变量,而不是使用该方法。此变量的初始值为nil,这是merge方法看到的值。

如果要引用该方法,则需要将其称为self.params=。这适用于任何具有此类方法的对象,而不仅仅是Sinatra。

为了避免这种混乱,更好的解决方案可能是使用不同的名称。类似的东西:

get '/' do
  defaults = { 'p1' => 'default1', 'p2' => 'default2' }
  normalized_params = defaults.merge(params)
  normalized_params.inspect
end

答案 2 :(得分:0)

我在架子宝石中发现了这个

http://www.rubydoc.info/gems/rack/Rack/Request#params-instance_method

您似乎可以通过params方法检索GET和POST数据,但您无法在其中写入。您必须改为使用update_paramdelete_param