Requiring files should not execute code

Accepted

Created

Context

In Ruby, require will execute the code in the required file. Typically, these files declare/define classes or modules only. But, Ruby is Ruby and you can put any code in these files and it will run when the file is required.

Concerns or Issues

For managing an app, care needs to be taken about when certain parts of the codebase are executed. We've all been bitten by trying to e.g. build assets in a Rails app only to have it fail because Redis could not be reached. This is partly because some gems or files, when required, execute potentially complex setup, instead of just declaring classes/modules.

Decision

All .rb files, when required, should only declare classes/modules, or require other files. They should not access the filesystem, connect to servers, or perform any other unexpected tasks beyond declaring classes/modules.

Options Considered, but Not Chosen

We considered a convention for some files, like exec_*.rb to indicate that requiring such files would invoke behavior beyond declaring a class. This was rejected as it's always possible to put code inside a method invocation. In particular, it's possible to make a method call require and set up Bundler, so there's no need to have an .rb file performing bootstrapping outside the context of invoking a method of a class or module.

System Qualities or Desired Consequences

This means any .rb can safely be required without worrying about odd side effects or failures due to missing filesystem or network resources.

Downsides

Certain bootstrapping or setup tasks require the instantiation of classes and invocation of methods in order to perform said setup. Achieving such setup by simply requiring a file will not be done.

Additional Rationale

Brut strives to make its behavior clear and explicit. A logical first step to achieving that is to separate the invocation of behavior from the assembly of an app's source files via require