Rack specifies
Rack应用程序是响应调用的Ruby对象(不是类)。
因此,一个简单的config.ru
看起来像这样:
class MyApp
def call(env)
[200, {"Content-Type" => "text/plain"}, ["Hello from Rack!\n"]]
end
end
run MyApp.new
而Rails生成这个:
# This file is used by Rack-based servers to start the application.
require ::File.expand_path('../config/environment', __FILE__)
run RailsApp::Application
所以,我想知道:当Rack指定它是一个对象而不是一个类时,为什么不run RailsApp::Application.new
?我错过了Rails::Application
有什么特别之处吗?
答案 0 :(得分:17)
这确实有点隐藏:)
RailsApp::Application
是Rails::Application
的子类,而Rails::Engine
的{{1}}是Rails::Railtie
。现在Rails::Railtie
有一个inherited
hook,只要子类继承自Railtie类(在本例中为Engine
),就会调用它。
此回调包含Rails::Railtie::Configurable
模块到子类中。在本单元中,您将找到神奇的第一部分。
在类上定义的method_missing
方法在类的实例上调用方法,该方法或多或少地解析为
RailsApp::Application.new.call(...)
此call
实例方法在Rails::Application#call
中定义,并执行典型的Rack处理。
可能还有更多的魔法使它不是100%相当,但应该大致是......
答案 1 :(得分:1)
Class也是一个Object。 Rack没有实例化app对象(这就是为什么它指定你需要提供对象),你在config.ru
中这样做,所以如果Rack发送'call'时Rails类对象遵循所有Rack规则,这应该不是问题。
在内部,我不知道Rails是否在call
上做了什么特别的事情。它甚至可以是一个工厂方法,它既吐出应用程序类的实例又运行它。但它不需要满足Rack。