Skip to content

Instantly share code, notes, and snippets.

@seangeo
Created June 30, 2012 03:19
Show Gist options
  • Save seangeo/3022012 to your computer and use it in GitHub Desktop.
Save seangeo/3022012 to your computer and use it in GitHub Desktop.
Using decorators to extend objects with roles without modifying the original object. A possible alternative to dynamic method binding described in Clean Ruby.
# Jim Gay's new book, Clean Ruby (http://clean-ruby.com), has a section on dynamically binding
# methods to objects with roles in a DCI context. He does this in a way that doesn't modify the
# original object, unlike extending the object with a model does. I found the solution clever
# but maybe a little bit unclear (but it's the first iteration of this part of the book, so I'm
# sure it will become more convincing later :).
#
# This is an alternative to that solution which uses Module extension on a simple wrapper/decorator
# object. The module's methods are added to the wrapper and it behaves as though the original object
# has been extended with the role, but the original is untouched. I haven't really seen this solution
# to the role extension problem anywhere else, but I'm sure I'm not the first to suggest it.
require 'delegate'
module Transferrable
def transfer_to(amount, to)
self.decrement(amount)
to.increment(amount)
end
end
source = Account.find(1)
destination = Account.find(2)
# This would go in a Context that needs the role.
transferrable_source = SimpleDelegate.new(source).extend(Transferrable)
transferrable_source.transfer_to(10, destination)
source.transfer_to(10, destination) # raises NoMethodError, that's good!
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment