如何让Sinatra与HTTPClient一起使用?

3
我将尝试创建一个Facade API,该API通过Sinatra接收请求,然后在后端发出Github API的HTTP请求。
在我的“hello world”脚本中,我有:
#!/usr/bin/ruby

require 'httpclient'
require 'sinatra'

get '/foo' do
    "hello world"
end

然而,它会遇到如下错误:
$ ./api.rb 
/usr/local/share/gems/gems/sinatra-1.4.3/lib/sinatra/base.rb:1408:in `run!': undefined method `run' for HTTP:Module (NoMethodError)
from /usr/local/share/gems/gems/sinatra-1.4.3/lib/sinatra/main.rb:25:in `block in <module:Sinatra>'

我不明白为什么会出现这种情况。如果我注释掉require 'httpclient'这一行,它就可以正常工作:

#!/usr/bin/ruby

#require 'httpclient'
require 'sinatra'

get '/foo' do
  "hello world"
end

$ ./api.rb 
[2013-06-26 21:43:12] INFO  WEBrick 1.3.1
[2013-06-26 21:43:12] INFO  ruby 1.9.3 (2013-05-15) [x86_64-linux]
[2013-06-26 21:43:12] WARN  TCPServer Error: Cannot assign requested address - bind(2)
== Sinatra/1.4.3 has taken the stage on 4567 for development with backup from WEBrick
[2013-06-26 21:43:12] INFO  WEBrick::HTTPServer#start: pid=31272 port=4567

我的猜测是Sinatra正在单独使用HTTPClient,发生了某种命名空间冲突。有没有办法同时使用HTTPClient和Sinatra呢?
好的,这里是所要求的信息:
$ gem list sinatra httpclient

*** LOCAL GEMS ***

sinatra (1.4.3)

$ gem out sinatra httpclient
bigdecimal (1.1.0 < 1.2.0)
io-console (0.3 < 0.4.2)
json (1.6.8 < 1.8.0)
rdoc (3.12 < 4.0.1)

我是这样确定httpclient版本的:

$ locate httpclient.rb
/usr/local/share/gems/gems/httpclient-2.3.3/lib/httpclient.rb
/usr/local/share/gems/gems/httpclient-2.3.3/test/test_httpclient.rb

我的操作系统是Fedora 17,虽然不确定这是否重要。


这与“全局” Ruby 没有任何关系。它应该是源代码中的某处。 - the Tin Man
在命令行中输入“gem list sinatra httpclient”。你正在运行哪些版本?“gem out sinatra httpclient”是什么意思?通过编辑问题将响应添加到底部,而不是添加注释。 - the Tin Man
更多线索:https://dev59.com/5nLYa4cB1Zd3GeqPZpmL - Casper
我使用Ruby 1.9.3-p429、Sinatra 1.4.3和HTTPClient 2.3.3成功地运行了代码。 - the Tin Man
@theTinMan 你是在 Thin 还是 WEBrick 上运行的? - Casper
显示剩余8条评论
1个回答

13

我找到了原因。HTTPClient定义了一个名为HTTP的模块。默认情况下,Sinatra查找具有命名空间名称HTTPWEBrick的Rack处理程序。

由于已经定义了HTTP命名空间,因此Sinatra实际上认为它是一个Rack处理程序。我认为这是Sinatra中的一个错误。在使用它之前,应该检查处理程序是否响应run方法。

无论如何,解决方法是使用Thin,或者如果您想使用WEBrick,则通过执行以下操作明确告诉Sinatra跳过自动Rack检测:

set :server, 'webrick'

这将防止Sinatra认为HTTPClient的HTTP模块是Rack处理程序。


+1 对他们来说做 responds_to(:run) 作为一个合理的检查是非常合理的。使用Thin也有优势。很好的发现! - the Tin Man
你们真是太棒了。非常感谢你们的帮助!我今天晚些时候会测试一下,并汇报结果。 - Marseille07
是的,我刚用thin测试了一下,结果很好。看起来thin是一个更好的Web服务器,所以我可以继续使用它。我还学会了如何配置Rack应用程序并使用增加的超时值启动thin。再次感谢大家! - Marseille07
我也遇到了这个问题 - 当我设置新的环境时,我没有意识到我没有安装thin。由于sinatra默认会首先尝试使用thin,所以我所要做的就是 'sudo gem install thin' - 然后再次启动应用程序。 - genegc

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接