Sinatra 不是从 twitter gem 开始的

问题描述:

当我尝试启动 sinatra 时,出现以下错误

when i try to start sinatra, i'm getting following error

/var/lib/gems/1.9.1/gems/sinatra-1.4.4/lib/sinatra/base.rb:1488:in start_server': undefined methodrun' for HTTP:模块(NoMethodError)

/var/lib/gems/1.9.1/gems/sinatra-1.4.4/lib/sinatra/base.rb:1488:in start_server': undefined methodrun' for HTTP:Module (NoMethodError)

require 'sinatra/base'
require_relative "twt.rb"

class SinatraApp < Sinatra::Base
    set :static, true
    set :public_folder, File.dirname(__FILE__) + '/static'

    get '/getuserinfo' do
        @user = twit.getuserinfo
        erb :userInfo
    end
end

SinatraApp.run!

在twt.rb"中,我需要 twitter (5.7.1)

in "twt.rb" i require twitter (5.7.1)

require 'twitter'

class Twit
    attr_accessor :client

    def initialize(consumer_key,consumer_secret,access_token,access_token_secret)           
        @client = Twitter::REST::Client.new do |config|
          config.consumer_key        = consumer_key
          config.consumer_secret     = consumer_secret
          config.access_token        = access_token
          config.access_token_secret = access_token_secret
        end
    end

    def getUserInfo
        return user = {     
            "name"=> client.current_user.name,
            "id" => client.current_user.id
        }
    end

    def showAllFriends
         client.friends.each { |item| puts item.name }       
    end

    def showFollowers
        client.followers.each { |item| puts item.screen_name }
    end

    def showAllTweets       
         client.user_timeline.each {|item| puts item.text}
    end

    def showAllUserTweets(userScreenName)                   
         client.user_timeline(userScreenName).each {|item| puts item.text}
    end

    def sendTweet(content)
        client.update(content)
    end
end

如果我删除 require_relative "twt.rb" 行,sinatra 工作正常.

if i remove require_relative "twt.rb" line sinatra works fine.

当您使用内置 Web 服务器运行 Sinatra 应用程序时(就像使用 SinatraApp.run! 一样),Sinatra 会尝试通过依次检查服务器列表以查看哪些服务器可用来确定要使用的服务器.实际列表 取决于 Ruby 的版本您正在使用,但它始终检查的服务器是net-http-server,简称为 HTTP.

When you run a Sinatra app using the built-in web server (as you do with SinatraApp.run!), Sinatra tries to determine which server to use by checking a list of servers in turn to see which is available. The actual list depends on the version of Ruby you are using, but one server that it always checks is net-http-server, which is simply named HTTP.

Sinatra 检查服务器可用性的方式是使用机架方法,调用 const_get 以尝试找到常量 Rack::Handler::.但是,由于 const_get 的工作方式,如果该常量不可用,但与 server-name 同名的*常量可用,则将返回该常量,不管是什么课.(这可以说是 Rack 中的一个错误).

The way Sinatra checks for the availability of a server is by using a rack method that calls const_get to try and find the constant Rack::Handler::<server-name>. However, due to the way const_get works, if that constant is not available, but a top level constant with the same name as server-name is, then that will be returned, whatever class it is. (This is arguably a bug in Rack).

Twitter gem 取决于http gem,然后又定义了一个HTTP模块.(使用像 HTTP 这样通用的东西来命名*模块可能不是一个好主意.

The Twitter gem depends on the http gem, and that in turn defines a HTTP module. (Naming a top-level module with something as generic as HTTP is arguably not a good idea).

所以在这种情况下发生的事情是 Sinatra 正在检查 HTTP 服务器是否可用,但 Rack 正在从 http 返回 HTTP 模块 gem,它不是服务器.不是机架服务器,它没有 run 方法,因此当 Sinatra 尝试将其用作一个方法时,您会收到错误 start_server': undefined method `run' for HTTP:Module代码>.

So what is happening in this case is Sinatra is checking to see if the HTTP server is available, but Rack is returning the HTTP module from the http gem, which isn’t a server. Not being a Rack server it doesn’t have a run method, so when Sinatra tries to use it as one you get the error start_server': undefined method `run' for HTTP:Module.

一种解决方法是不使用内置服务器,例如您发现使用 config.ru 文件并使用 rackup 启动应用程序的方式.

One workaround is not to use the built-in server, such as the way you have discovered using a config.ru file and starting the app with rackup.

另一种解决方案是明确指定要在您的 Sinatra 应用中使用的服务器.例如,您可以安装 Thin,然后使用:

Another solution is to explicitly specify the server to use in your Sinatra app. For example you could install Thin, and then use:

set :server, 'thin'

事实上,简单地安装 Thin 就足够了,因为在 HTTP 之前搜索 Thin,但您可能最好明确设置要使用的服务器.如果您因任何原因无法安装任何其他服务器,您可以改用 Webrick:

In fact simply installing Thin would be sufficient as Thin is searched for before HTTP, but you are probably better explicitly setting the server to use. If you cannot install any other server for any reason you could use Webrick instead:

set :server, 'webrick'