为什么Rails生成一个运行类而不是对象的config.ru?

时间:2013-03-22 14:09:25

标签: ruby-on-rails ruby rack

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有什么特别之处吗?

2 个答案:

答案 0 :(得分:17)

这确实有点隐藏:)

RailsApp::ApplicationRails::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。