Created
June 17, 2009 20:22
-
-
Save tjstankus/131482 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Slight modifications to code posted by Gregory Brown at http://pastie.org/515450 | |
require 'delegate' | |
module Decoration | |
def decorator_for(*types, &block) | |
types.each do |type| | |
decorators[type] = Module.new(&block) | |
end | |
end | |
def decorators | |
@decorators ||= {} | |
end | |
def decorate(target) | |
obj = SimpleDelegator.new(target) | |
# walk in reverse order so most specific patches get applied LAST | |
target.class.ancestors.reverse.each do |a| | |
if decorators[a] | |
obj.extend(decorators[a]) | |
end | |
end | |
return obj | |
end | |
end | |
class MyView | |
extend Decoration | |
attr_reader :target | |
decorator_for Numeric, String do | |
def double | |
self * 2 | |
end | |
end | |
decorator_for Symbol do | |
def double | |
(self.to_s * 2).to_sym | |
end | |
end | |
decorator_for Array do | |
def double | |
map { |o| MyView.new(o).double } | |
end | |
end | |
decorator_for Hash do | |
def double | |
h = {} | |
self.each { |key, val| h[MyView.new(key).double] = MyView.new(val).double } | |
h | |
end | |
end | |
decorator_for Object do | |
def double | |
raise "Don't know how to double #{self.inspect}" | |
end | |
end | |
def initialize(target) | |
@target = self.class.decorate(target) | |
end | |
def double | |
target.double | |
end | |
end | |
p MyView.new('aaa').double | |
p MyView.new(49).double | |
p MyView.new(:a).double | |
p MyView.new(['b', 6]).double | |
p MyView.new({:a => 1}).double | |
class MyCollaborator | |
def double | |
'MyCollaborator#double' | |
end | |
end | |
p MyView.new(MyCollaborator.new).double |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment