Mechanize & Sinatra conflict

我只是一个虾纸丫 提交于 2019-12-23 10:42:22

问题


I've writter a simple web crawler using Mechanize as a command-line utility. Then I decided to create web app with Sinatra, but got stuck with this error when trying to run the local webserver:

/home/nazar/.rvm/gems/ruby-2.0.0-p195/gems/sinatra-1.4.2/lib/sinatra/base.rb:1569:in `run!': undefined method `run' for HTTP:Module (NoMethodError)
from /home/nazar/.rvm/gems/ruby-2.0.0-p195/gems/sinatra-1.4.2/lib/sinatra/main.rb:25:in `block in <module:Sinatra>'

The source code is dead simple:

require 'sinatra'
require 'mechanize'

get '/' do
   # mechanize stuff
end

I've gone through some investigation and managed to find out that 2 gems work fine separately, but only combining them causes the issue. Can anyone point out what the problem might be?


回答1:


Most probably you are are overriding methods like get with mechanize. Try to wrap your Sinatra application into an application class. That may resolve the issue.

require 'sinatra/base'

class MyApp < Sinatra::Base
  get '/' do
    # mechanize stuff
  end
end

Find out more about that approach in the Sinatra documentation.




回答2:


I had the same issue and was able to solve it by installing and using Thin as my local webserver.

I dug into sinatra source and see that it tries to guess what server to use when running, in order, which you can see via irb:

1.9.3p194 :011 > require 'sinatra'
 => true 
1.9.3p194 :012 > Sinatra::Base
 => Sinatra::Base 
1.9.3p194 :014 > Sinatra::Base::server
 => ["thin", "puma", "HTTP", "webrick"] 

Normally Sinatra would fall back to webrick but Mechanize has a Module named HTTP so it tries to use that as a server, which doesn't work of course.

I am using this in a run.sh script to specify Thin:

rerun   -- thin start  --port=4567 -R config.ru



回答3:


As mentioned by iltempo and user2632580, the reason this fails is the list of servers Sinatra tries by default, failing on HTTP which the Mechanize gem has overriden.

An alternative approach to overcome this is to supply a different list of servers for Sinatra to try as per the documentation at http://www.sinatrarb.com/configuration.html (see "Built-in Settings" > ":server").

Example script:

require 'sinatra'
require 'mechanize'

set :server, %w[thin puma reel webrick]

get '/' do
   "Hello world!"
end

This list in the example is based on the current value of Sinatra::Base::server minus HTTP



来源:https://stackoverflow.com/questions/16777850/mechanize-sinatra-conflict

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!