Traitor is a basic implementation of [Traits](http://en.wikipedia.org/wiki/Trait_(computer_programming) (duh) for Ruby 2.0.
Also, it might be the only library in the world that needs refinements.
Add this line to your application's Gemfile:
rvm install ruby-2.0.0-preview1 gem 'traitor'
And then execute:
Or install it yourself as:
$ gem install traitor
Behavior reusability through Traits
Traits are like Ruby modules in the sense that they can be used to define composable units of behavior, but they are not included hierarchically. They are truly composable, meaning that are pieces that must either fit perfectly or the host object must provide a way for them to do it, normally resolving conflicts by explicitly redefining the conflicting methods.
Say we have a
Colorable = Trait.new do attr_accessor :color def ==(other) other.color == color end end
Shapeable = Trait.new do attr_accessor :sides def ==(other) other.sides == sides end end
Now we would like an object composed of those two traits:
class Rectangle uses Shapeable uses Colorable end
This obviously doesn't work -- if we try to call #== on a
doesn't know which implementation should it call.
See the error:
Rectangle.new == Rectangle.new # TraitConflict: Conflicting methods: #==
Traits have no hierarchy, so no one prevails over the others. The only way to use both traits is to provide an explicit conflict resolution:
class Rectangle uses Shapeable uses Colorable def ==(other) colorable_equal = trait_send(Colorable, :==, other) shapeable_equal = trait_send(Shapeable, :==, other) colorable_equal && shapeable_equal end end
Now we can use
#== safely because we control how conflicts are resolved.
Note that we have access to either implementation via
- Fork it
- Create your feature branch (
git checkout -b my-new-feature)
- Commit your changes (
git commit -am 'Added some feature')
- Push to the branch (
git push origin my-new-feature)
- Create new Pull Request