configuration_dsl¶ ↑
Easily configure classes and objects using a DSL.
Description¶ ↑
configuration_dsl encapsulates the pattern of using a DSL to “configure” objects and/or classes:
class MyAwesomeClass ... some setup code here ... configure do greeting "Hello!" count 5 end end MyAwesomeClass.configuration.greeting # => "Hello!" MyAwesomeClass.configuration.count # => 5
Usage¶ ↑
Bet you’re wondering what goes in that “some setup code here” placeholder. It’s nothing too complicated. Here’s a complete example.
module MyConfiguration def greeting(s) s end def count(n) n end end require "configuration_dsl" class MyAwesomeClass extend ConfigurationDsl configure_with(MyConfiguration) configure do greeting "Hello!" count 1 end end MyAwesomeClass.configuration.greeting # => "Hello!" MyAwesomeClass.configuration.count # => 1
The basic idea is that you define a module with your configuration options, then you configure your class/object with it.
Why a module?¶ ↑
Why are the configuration options stored in a module? It makes for pretty documentation! Just run rdoc on your configuration module.
Default values, lazily evaluated values and modified values.¶ ↑
Default values are supported in an intuative way. If you specify a block for a value, then it is lazily evaluated when you try to access the value for the first time.
class MyClass extend ConfigurationDsl configure_with Module.new { def name(s = "Christopher") s end def time(t) t end def age(n) n - 1 end def callback(proc) proc end } configure do puts Time.now # => 2011-08-02 01:11:50 -0400 time{ Time.now } age 31 greeter Proc.new{ |name| "Hello, #{name}" } end end sleep(2) MyClass.configuration.time # => 2011-08-02 01:11:52 -0400 MyClass.configuration.age # => 30 MyClass.configuration.name # => "Christopher" MyClass.configuration.greeter.call("Chris") # => "Hello, Chris"
Make sense?
Working with objects¶ ↑
configuration_dsl works with plain objects (in addition to classes). Given the module MyConfiguration from our previous examples:
foo = Foo.new foo.extend(ConfigurationDsl) foo.configure_with(MyConfiguration) foo.configure do greeting "What up?" count 2 end foo.configuration.greeting # => "What up?" foo.configuration.count # => 2
Working with classes¶ ↑
If you use configuration_dsl with classes, then derived classes should inherit the configuration in a sane and predictable way.
Callback¶ ↑
You can set a callback to be called after each time configure
is called. Just pass a block to configure_with
.
class MyClass extend ConfigurationDsl configure_with(SomeConfigurationModule) do @configure_count ||= 0 @configure_count += 1 end configure do some_option "something" end end MyClass.configure do another_option "something else" end MyClass.instance_variable_get(:@configure_count) # => 2
This is useful if you need to run some kind of initialization code after your class or object has been configured.
Configuring the configure
and configuration
methods¶ ↑
You can use different methods for #configure and #configuration.
class MyClass extend ConfigurationDsl configure_with(SomeModule, :method => :setup, :storage => :settings) setup do setting1 "blah" setting2 "bleh" end end MyClass.settings.setting1 # => "blah" MyClass.settings.setting2 # => "bleh"
Multiple Configurations¶ ↑
configuration_dsl
supports multiple configurations for a single object.
module PersonalConfig def name(s) s.to_s end def age(n) n.to_i end end module AccountsConfig def twitter(name) name.to_s end def email(email) email.to_s end end class MyClass extend ConfigurationDsl configure_with(PersonalConfig, :method => :configure_personal, :storage => :personal_configuration) configure_with(AccountsConfig, :method => :configure_accounts, :storage => :accounts_configuration) configure_personal do name "Christopher" age 31 end configure_accounts do twitter "cjbottaro" email "cjbottaro@alumni.cs.utexas.edu" end end MyClass.personal_configuration.name # => "Christopher" MyClass.personal_configuration.age # => 31 MyClass.accounts_configuration.twitter # => "cjbottaro" MyClass.accounts_configuration.email # => "cjbottaro@alumni.cs.utexas.edu"
Contributing to configuration_dsl¶ ↑
-
Check out the latest master to make sure the feature hasn’t been implemented or the bug hasn’t been fixed yet
-
Check out the issue tracker to make sure someone already hasn’t requested it and/or contributed it
-
Fork the project
-
Start a feature/bugfix branch
-
Commit and push until you are happy with your contribution
-
Make sure to add tests for it. This is important so I don’t break it in a future version unintentionally.
-
Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
Copyright¶ ↑
Copyright © 2011 Christopher J Bottaro. See LICENSE.txt for further details.