Project

hooker

0.01
No commit activity in last 3 years
No release in over 3 years
Hooker provides a simple registry of hooks or extension points, enabling decoupled run time configuration in terse but straight ruby syntax. Inspiration includes Emacs Hook Functions and other ruby-based configuration files.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Development

~> 4.7.4
 Project Readme

Hooker¶ ↑

Description¶ ↑

Hooker provides a simple registry of hooks or extension points, enabling decoupled run time configuration in terse but straight ruby syntax. Inspiration includes Emacs Hook Functions and other ruby-based configuration files.

Features¶ ↑

  • Hook Procs may be added by the configuration source in any order.

  • Hook Procs may be chained and combined via various conventions: Hooker.apply, Hooker.inject, Hooker.merge.

  • Hook Procs are executed only when applied by the extended application. Thus a single configuration source may include hook Procs that are left un-executed in certain contexts. This is useful when configuring across several different (contextually loaded) modules from one source.

  • Optional or implicit scoping of keys, providing a two level Hook [:scope, :key] hierarchy. The default scope is :default.

  • Optional Hooker.log_with extension point

  • Can check and list hooks that were not applied, including the call site of where added, allowing you to test your configurations and avoid typos.

  • Thread safe (though you should strive to complete all configurable bootstrapping in the main thread).

Synopsis¶ ↑

Lets say an application has a ‘Job’ it would like to support configuration hooks on. First arrange for any number of configuration sources to be loaded via Hooker.load_file. Then apply any loaded hook procs to an instance of your Job, like so:

require 'hooker'

Hooker.load_file( "config.rb" ) if File.exist?( "config.rb" )
job = Hooker.apply( :job, Job.new )

You could also use Hooker.register_config with an OptionParser to support a -c/--config FILE flag for specifying the configuration source.

If Job is to be configured via setters, then the configuration source might look like this:

Hooker.with do |h|
  h.setup_job do |j|
    j.workers = 3
    j.timeout = 10 * 60 #seconds
  end
end

Alternatively, if Job takes a Hash on construction for configuration, use Hooker.merge like so:

opts = Hooker.merge( :job, { workers: 2 } ) #defaults
job = Job.new( opts )

…and Hash syntax in the configuration source. Note that unlike JSON or YAML, the configuration remains fully interpreted for greater expressiveness, for example sharing variables across different configured objects:

Hooker.with do |h|
  cpus = 3

  h.setup_job do
    { workers: cpus + 1,
      timeout: 10 * 60 }
  end

  h.setup_connection_pool do
    { size: cpus }
  end
end

Hooker can be yielded to the configuration source via an alternative Module.method name, to fully encapsulate its use:

class Chaplain
  def self.configure( &block )
    Hooker.with( :church, &block )
  end
end

…supports the configuration source:

Chaplain.configure do |c|
  c.setup_job do |j|
    j.workers = 3
    j.timeout = 10 * 60 #seconds
  end
end

License¶ ↑

Copyright © 2011-2015 David Kellum

Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at:

www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.