我对一些实际上并不是一个实际问题的东西感到困惑 - 只是一个概念上的难题 - 关于在Heroku上部署Sinatra应用程序。
我有两个应用程序,几乎在每个方面都相同,只是一个将大多数逻辑放在一个不包含Sinatra :: Base类的文件中,并使用'require otherfilename'来获取它需要的逻辑。 Sinatra:Base类名为Kincalc。
对于包含一个文件中所有逻辑的应用程序(即包含Sinatra:Base类的同一文件),在我的config.ru文件中,最后一行显示“运行Sinatra :: Application”并启动精细。但在另一个应用程序中,如果我将其作为最后一行包含,则应用程序正确上传并说它“已部署到Heroku”但它会显示“未找到”消息。当我有最后一行读'run Kincalc'时,它加载正常。
我已经来回检查了这两个应用程序是如何构建的,除了一个人使用第二个文件作为逻辑(也是在root用户)的事实。为什么这是一个问题,还是这真的是问题?当我尝试将第二个文件(没有Sinatra类的文件)放在一个单独的lib文件夹中时,它在我调用类名时仍然有效,但在我调用“Sinatra :: Application”时却不行。
答案 0 :(得分:7)
顶级代码将委托给Sinatra::Application
,因此这将是运行经典应用程序的场景:
# app.rb
require 'sinatra'
get '/' do
'hi'
end
# config.ru
require './app'
run Sinatra::Application
如果您定义模块化应用程序,则可以像这样运行:
# app.rb
require 'sinatra/base'
class Kincalc < Sinatra::Base
get '/' do
'hi'
end
end
# config.ru
require './app'
run Kincalc
现在我假设你要做的是这个:
# otherfilename.rb
require 'sinatra'
get '/' do
'hi'
end
# app.rb
require 'sinatra/base'
class Kincalc < Sinatra::Base
require './otherfilename'
end
# config.ru
require './app'
run Kincalc # Sinatra::Application seems to work
您遇到的行为(获取404文件未找到)实际上是正确的,因为require
并不关心它被调用的词法范围。请查看以下示例
# a.rb
puts "in a, top level: #{self.inspect}"
module Example
puts "in a, nested: #{self.inspect}"
require 'b'
end
# b.rb
puts "in b: #{self.inspect}"
结果输出应为:
in a, top level: main
in a, nested: Example
in b: main
所以,如果你想使用一个模块化应用程序,你应该这样做:
# otherfilename.rb
Kincalc.get '/' do
'hi'
end
或者再次打开课程:
# otherfilename.rb
class Kincalc
get '/' do
'hi'
end
end
或者您实际上可以otherfilename.rb
在Sinatra::Application
上创建定义并在Kincalc
中使用它。
# app.rb
require 'sinatra/base'
require './otherfilename'
class Kincalc < Sinatra::Base
use Sinatra::Application
end
或者您可以更改委托顶级DSL方法的位置:
# app.rb
require 'sinatra/base'
class Kincalc < Sinatra::Base
Sinatra::Delegator.target = self
require './otherfilename'
end