2013-03-22 6 views
8

Rack specifiesPerché Rails generare un config.ru che gestisce una classe, non un oggetto?

Un'applicazione Rack è un oggetto rubino (non una classe) che risponde a chiamare.

Di conseguenza, un semplice config.ru assomiglia a questo:

class MyApp 
    def call(env) 
    [200, {"Content-Type" => "text/plain"}, ["Hello from Rack!\n"]] 
    end 
end 

run MyApp.new 

mentre Rails genera questo:

# This file is used by Rack-based servers to start the application. 

require ::File.expand_path('../config/environment', __FILE__) 
run RailsApp::Application 

Quindi, mi chiedo: Perché non run RailsApp::Application.new quando Rack specifica che sia un oggetto, non una classe? C'è qualcosa di speciale nello Rails::Application che mi manca?

risposta

15

Questo è davvero un po 'nascosto :)

RailsApp::Application è una classe figlia di Rails::Application, che a sua volta è un Rails::Engine che è un Rails::Railtie. Ora Rails::Railtie ha un inherited hook che si chiama ogni volta che una classe figlia eredita dalla classe Railtie (in questo caso Engine).

Questa richiamata include il modulo Rails::Railtie::Configurable nella sottoclasse. In questo modulo trovi la prima parte della magia.

Procedimento method_missing che viene definito sulla classe chiama il metodo su un'istanza della classe, che più o meno risolve per

RailsApp::Application.new.call(...) 

Questo metodo call esempio è definito nella Rails::Application#call e fa il tipico passare Rack .

Probabilmente c'è ancora un po 'di magia in più che lo rende non equivalente al 100% ma dovrebbe essere circa ...

1

Una classe è anche un oggetto. Rack non istanziare l'oggetto applicazione (che è il motivo per cui specifica è necessario fornire l'oggetto), lo fate in config.ru, quindi fornito l'oggetto della classe Rails segue tutte le regole rack quando Rack invia 'chiamata', non dovrebbe essere un problema.

Internamente, io non so se Rails fa nulla di speciale sul call. Potrebbe anche essere un metodo factory che sputa un'istanza della classe dell'applicazione e la esegue. Ma non ha bisogno di essere per soddisfare Rack.

Problemi correlati