rails/rails — pull request #7225 by josevalim (2012-08-01 14:38:52+00:00)
Title: Improve eager load on Rails

PS: This pull request is a work in progress. Read this description and commit messages for the rationale for each change.

Today, eager loading an application is coupled with the config.cache_classes configuration. This means that every time we cache classes, we eager load the app. This is not necessarily true, for example in test environment an application could benefit of not eager loading the whole application when running a single test file, [as the results reported here](https://gist.github.com/2947894).

This proposal discuss some changes for Rails 4 to make booting more flexible and consistent.

## config.eager_load

The first part of the proposal is to add a config.eager_load that says when to eager load the application. By default, we want these settings to be:

# development
config.cache_classes = false
config.eager_load = false

# test
config.cache_classes = true
config.eager_load = false # you may want to turn this to true if using spork

# production
config.cache_classes = true
config.eager_load = true

Notice that running a rake task **always** disables eager load (this is hardcoded in rails source today).

## config.eager_load_namespaces

Rails also has a boolean configuration named `config.preload_frameworks` that preloads frameworks. I don't like this configuration because it is very tied to Rails and its frameworks. I propose instead `config.eager_load_namespaces` as a configuration generic enough not only to support Rails frameworks, but any gem or extension. We should be able to eager load any namespace by adding it to the list:

config.eager_load_namespaces << DataMapper

And now, whenever `config.eager_load` is true, we will invoke `DataMapper.eager_load!` to do the proper setup.

The idea of registering namespaces (and not lambdas) is that a user should be able to remove a namespace of the list if it is causing problems (or if they don't really need to eager load it).

Another nice thing about this approach is that all engines (and therefore any Rails application) already implements the `eager_load!` method, so they could be added by default to the `config.eager_load_namespaces` array, unifying both preload frameworks and eager load approaches.