Truck
Truck is an alternative autoloader that doesn't pollute the global namespace. Specifically, it does not load constants into Object
; rather, it loads them into Contexts that you define. This has three main advantages:
reload!
is very fast;Object.send(:remove_const, :MyContext)
does the trick- You can have multiple autoloaders running in parallel contexts
- Eliminates the need for
fork()
based preloaders likezeus
andspring
. Instead, load your gems, define your contexts, and safelyreload!
them between each test run.
Installation
Add this line to your application's Gemfile:
gem 'truck'
And then execute:
$ bundle
Or install it yourself as:
$ gem install truck
Usage
Unlike ActiveSupport's autoloader, truck requires a bit of setup for each context. An example:
Truck.define_context :MyContext, root: "/path/to/context/root"
Also, after defining all your contexts, you'll want to boot everyone up:
Truck.boot!
You'll want to define all your contexts, then fork/spawn threads, then have every sub process invoke Truck.boot!
separately.
Referencing constants
Suppose you had a class called Foo
living in /path/to/context/root/foo.rb
:
# /path/to/context/root/foo.rb
class Foo
def self.
Bar.hello_world
end
end
# /path/to/context/root/bar.rb
class Foo
def self.hello_world
"hello, world!"
end
end
Foo
can reference Bar
without an explicit require. So how does the world outside of MyContext
reference objects?
MyContext.resolve_const("Bar")
This works with namespaced constant names, too:
MyContext.resolve_const("Foo::Bar::Baz")
Other
MyContext
has some other interesting methods on it:
# Wipe the whole context and reload it (also aliased as reload!)
MyContext.reset!
# Kill the context
MyContext.shutdown!
# Eagerly load the entire context into memory (good for production)
MyContext.eager_load!
These methods are also of course on Truck
as well, and invoke the same operations on every context.
Autoload Paths
By default, the root
you pass to the Context
is your autoload paths. You can alternatively supply a list of autoload paths relative to root
:
Truck.define_context(
:MyContext,
root: "/path/to/context/root",
autoload_paths: %w(app/models app/controllers lib)
)
Compatibiilty
Currently, truck has been tested against 2.1.1. It uses refinements internally. The plan is to support recent rubinius releases as well.
Contributing
- Fork it ( https://github.com/ntl/truck/fork )
- Create your feature branch (
git checkout -b my-new-feature
) - Commit your changes (
git commit -am 'Add some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create a new Pull Request