Created
February 26, 2015 13:25
-
-
Save bsodmike/b878b2a2b160d4056209 to your computer and use it in GitHub Desktop.
Simple Decorator Using Ruby Delegate for Ruby 2.1.5 & Rails 4
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
module Project | |
module Decorators | |
module Draperize | |
def self.included _klass | |
_klass.class_eval { extend ClassMethods } | |
end | |
module ClassMethods | |
# Initialize a new decorator instance by passing in | |
# an instance of class `_klass`. | |
# | |
# When passing in a single object, using `.decorate` is | |
# identical to calling `.new`. | |
def decorate(component) | |
new(component) | |
end | |
end | |
end | |
require 'delegate' | |
class Base < SimpleDelegator | |
def initialize(component) | |
super | |
@component = component | |
end | |
def class | |
__getobj__.class | |
end | |
end | |
class ProductDecorator < Base | |
include Draperize | |
# Add methods to decorate `component` | |
def decorated? | |
"Why, yes! Here's your decorated product '#{name}' (#{@component})" | |
end | |
end | |
end | |
end | |
class Product | |
def initialize | |
@name = "SPAM!" | |
end | |
attr_reader :name | |
end | |
p = Product.new | |
dp = Project::Decorators::ProductDecorator.decorate(p) | |
puts "p methods: #{p.methods.count}\n" | |
puts "dp methods: #{dp.methods.count}\n" | |
extra_methods = ((p.methods | dp.methods) - (p.methods & dp.methods)) | |
puts "Decorated methods in dp: #{extra_methods.inspect}\n" | |
puts "Calling dp#decorated?: #{dp.decorated?}\n" | |
puts "dp class: #{dp.class}\n" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
References
Thanks
To David (@workmad3) for spotting an obvious blunder on my part!