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 method
run' 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!
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
if i remove require_relative "twt.rb" line sinatra works fine.
i found the solution. i launch sinatra with config.ru and it works now.
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 namedHTTP
.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 constantRack::Handler::<server-name>
. However, due to the wayconst_get
works, if that constant is not available, but a top level constant with the same name asserver-name
is, then that will be returned, whatever class it is. (This is arguably a bug in Rack).The Twitter gem depends on the
http
gem, and that in turn defines aHTTP
module. (Naming a top-level module with something as generic asHTTP
is arguably not a good idea).So what is happening in this case is Sinatra is checking to see if the
HTTP
server is available, but Rack is returning theHTTP
module from thehttp
gem, which isn’t a server. Not being a Rack server it doesn’t have arun
method, so when Sinatra tries to use it as one you get the errorstart_server': undefined method `run' for HTTP:Module
.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 withrackup
.Another solution is to explicitly specify the server to use in your Sinatra app. For example you could install Thin, and then use:
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: