Alki loader is a library for using "non-standard" source files in your project.
What is a non-standard source file?
Generally a ruby source file follows these rules:
It should be placed in a directory that is in
$LOAD_PATH, so that it can be loaded using
It should define one ore more constants.
Ideally, it should just define a constant that is the "class-ified" version of the relative path of the file (if a directory
$LOAD_DIRand there is a file called
/project/lib/my_mod/my_class.rbthen the constant defined within it should be
This works well much of the time, but often enough it’s nice to break some of these rules.
For example, you might want files in directories in your project like
app but don’t want
to add those to
$LOAD_PATH because it could cause conflicts, or maybe you have files that you don’t
want to just define a module or class (like a DSL).
Alki::Loader provides tools that enable these patterns while still allowing you to use these files in standard ways.
There are three main components of Alki::Loader:
Allows registering directory and file paths with fake "names" so, for example, your projects
configdirectory could be registered with the name
my_project/config. Now when calling
require 'my_project/config/my_config'Ruby will load
require 'my_config'will still find nothing).
Allows registering directory and file paths with "builder" objects and configuration values. Files under these paths put their code in an unevaluated block that is passed to the builder so that it can process it and ultimately define the expected constant for that path with a value.
To allow the other two components to work, paths must be registered with Alki::Loader. This can be done anytime in code but can also be set by putting register calls in an
alk_loader.rbfile in any directory in
Add this line to your application’s Gemfile:
And then execute:
Or install it yourself as:
$ gem install alki-loader
Once the library is required you can require files as you normally would.
To register a path, use
Alki::Loader.register(path,settings). This can be called anywhere at any
time, but to make sure your paths are registered before they’re needed, it’s best to use an
To use one create a
alki_loader.rb file in whatever directory in your project is in
lib). It should just contain normal
The path argument to register should either be an absolute path, or a path relative to directory of the calling file.
For example, if you have an
Alki::Loader.register '../config', name: 'my_project/config'
It will register
/project/config to the name
If path registrations exist for multiple prefixes of the same file, the longest one will be used.
Alki::Loader.register '../config', name: 'my_project/config' # require 'my_project/config/initializers/foo' => config/initializers/foo.rb Alki::Loader.register '../config/environments', name: 'my_project/environments' # require 'my_project/environments/development' => config/environments/development.rb
When registering a path, the second argument is hash of settings to configure the path. These can be arbitrary key/value pairs but there are two setting values with special meaning.
Provide a name for the translater to use for this path. Will translate just the registered path and leave the rest of the path the same when changed.
Set the builder object, if one is wanted. Can be any object with a
A file that is to be built using a builder should always be in an Alki block:
Alki do # stuff goes here end
When the file is loaded, the builder object registered for the path will be called like so:
builder.build settings, &blk
blk is the unevaluated block from the file, and
settings is a hash containing all of the
settings registered to the path, along with two extra settings so the builder knows what file it’s
What would be passed to
The "class-ified" version of the name, following the typical rules for translating require paths into constant names. No special rules are used for abbreviations.
For example, if you just wanted to save some typing and have ruby infer your class names from the file path, you could create a builder like:
module SimpleClassBuilder def self.build(settings,&blk) # Alki::Support provides a handful of basic utility methods. # create_constant will create the named constant with the given value. klass = Class.new(&blk) Alki::Support.create_constant settings[:constant_name], klass end end
Then register it with alki_loader.
Alki::Loader.register 'my_project', builder: 'simple_class_builder'
Now classes can be added.
Alki do def self.hello puts "Hello World" end end
require 'alki/loader' require 'my_project/my_class'
Now we can reference
$ bundle exec irb -Ilib 2.4.1 :001 > require 'my_project' => true 2.4.1 :002 > MyProject::MyClass.hello Hello World => nil 2.4.1 :003 >
The gem is available as open source under the terms of the MIT License.