DumbDelegator
Ruby provides the delegate
standard library.
However, we found that it is not appropriate for cases that require nearly every call to be proxied.
For instance, Rails uses #class
and #instance_of?
to introspect on model classes when generating forms and URL helpers.
These methods are not forwarded when using Delegator
or SimpleDelegator
.
require "delegate"
class MyAwesomeClass
# ...
end
o = MyAwesomeClass.new
d = SimpleDelegator.new(o)
d.class #=> SimpleDelegator
d.is_a? MyAwesomeClass #=> false
DumbDelegator
, on the other hand, forwards almost ALL THE THINGS:
require "dumb_delegator"
class MyAwesomeClass
# ...
end
o = MyAwesomeClass.new
d = DumbDelegator.new(o)
d.class #=> MyAwesomeClass
d.is_a? MyAwesomeClass #=> true
Usage
Rails Model Decorator
There are many decorator implementations in Ruby.
One of the simplest is "SimpleDelegator
+ super
+ __getobj__
," but it has the drawback of confusing Rails.
It is necessary to redefine #class
.
We've also observed the need to redefine #instance_of?
for URL helpers.
With DumbDelegator
, there's not a need for this hackery because nearly every possible method is delegated:
require "dumb_delegator"
class Coffee
def cost
2
end
def origin
"Colombia"
end
end
class Milk < DumbDelegator
def cost
super + 0.4
end
end
class Sugar < DumbDelegator
def cost
super + 0.2
end
end
coffee = Coffee.new
Sugar.new(Milk.new(coffee)).cost #=> 2.6
Sugar.new(Sugar.new(coffee)).cost #=> 2.4
Milk.new(coffee).origin #=> Colombia
Sugar.new(Milk.new(coffee)).class #=> Coffee
Installation
Add this line to your application's Gemfile:
gem "dumb_delegator"
And then execute:
$ bundle
Or install it yourself as:
$ gem install dumb_delegator
Contributing
- 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
Contribution Ideas/Needs
- Ruby 1.8 support (use the
blankslate
gem?)