Find file
Fetching contributors…
Cannot retrieve contributors at this time
144 lines (105 sloc) 5.02 KB


A standard pattern to easily define and add behavior to a global behavior repository.
This pattern contains a macro that makes it easier to add such behaviors to Ruby classes of your choice.
The Behave pattern will be demonstrated by the troles gem for adding role behavior.

Behave also makes it easy to support multiple kinds of datastores via the schemaker gem,
that takes care of configuring your model relationships.



    #configure! - applies the configuration to the subject class or module

The Behave::Config is the base class of a Behavior configuration?

        configuration_class -> Behave::Decorator::Configuration

        config  -> Trole::Config instance  < Behave::Config
        store   -> Trole::Storage instance < Behave::Storage
    :troles =>
        config  -> Troles::Config instance  < Behave::Config
        store   -> Troles::Storage instance < Behave::Storage

Any module/class that can have behaviors, contains a hash ‘behaviors’ of named behaviors.
Each key in this hash points to a Behavior instance.


        configuration_class - inherits from module Behave::Decorator::Configuration
          config_class  - Troles::Config <  Behave::Config
          storage_class - Troles::Storage < Behave::Storage


The Repository contains all the behaviors currently available to all modules and classes.


Note. In the following, the ‘subject’ is the module or class that is the target on which to apply the behavior.

First you must define your behavior and then register it to the singleton Behavior Repository like this:

Behave::Repository.register_behavior(:hello) do |behavior|
  behavior.configuration_class = MyBehavior::Configuration

This is something you do for your Behavior “plugin”. This step has no relation to how it is used and configured on the subject.

After you have registered a behavior, you can apply it to various subjects (modules or classes) by using the #behavior macro, made available for any Module.

class User
  behavior(:trole_groups).configure_with :strategy => :ref_one do |config|
    strategy.orm = :mongoid
    strategy.auto_load = true

This will initially add a #behaviors collection to the subject class/module at the class level.

    :trole  -> Behave::Behavior
    :troles -> Behave::Behavior

The #behaviors collection of the subject class is populated by instances of Behave::Behavior.
Each such behavior has a relationship to a Behave::Decorator instance with the same name, registered in the repository (registered_behaviors hash).

    :trole -> Behave::Decorator

A Behave::Decorator instance has a Behave::Decorator::Configuration object that knows how to configure the behavior in a given context.

The Behave::Decorator::Configuration encapsulates concepts such as storage, strategy etc. and can do schema/model configuration (using schemaker).

Given strategy, ORM and some other options, the Behave::Decorator::Configuration instance will know how to load the right
data store adapter and find the right classes for storage, strategy etc. using specific loaders for each.

The Behave::Behavior instance will configure the subject using the Behave::Decorator#decorate method.

The result of the #behavior call is a Behave::Behavior object. If you call #configure_with on this Behavior object, you can configure how the behavior is to be applied to the subject.

The result of the #configure is a Behave::Config object, where you then lastly call #configure! to apply the configurations on the subject (late binding).

See the code for more details…

Note: This is currently work in progress… the above is subject to change!

Contributing to behave

  • 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 © 2011 Kristian Mandrup. See LICENSE.txt for
further details.