Sinatra:无法合并参数哈希

Sinatra: params hash cannot be merged

我想将散列与默认参数和请求中给出的实际参数合并。当我调用这个看似无辜的脚本时:

#!/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赋值给一个参数,为什么class Hash但是在defaults.merge params中却抛出异常?

有什么想法吗?

您的代码抛出错误,因为当您调用 defaults.merge(params)paramsnil。我假设您正在尝试将 defaultsrequest.params 合并,其中应包含 GET 中的参数。

更改此行

params = defaults.merge(params)

至此

params = defaults.merge(request.params)

我在架子上找到了这个 gem

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

似乎可以通过params方法获取GET和POST数据,但是不能写入。您必须改用 update_paramdelete_param

这是由 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