Skip to content

Instantly share code, notes, and snippets.

@jbgo
Created February 7, 2012 19:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jbgo/1761367 to your computer and use it in GitHub Desktop.
Save jbgo/1761367 to your computer and use it in GitHub Desktop.
Decorate all methods in a module - don't try this at home
module Foo
def foo
puts bar
return 42
end
def what(a, b)
puts "#{bar} = #{a} + #{b}"
return 42
end
def how(a, b)
result = yield a, b
puts "#{bar}: #{result}"
return 42
end
end
module Decorator
class << self
def decorate(klass, mod, &block)
klass.class_eval do
include mod
mod.instance_methods.each do |name|
class_eval "alias :#{name}_undecorated :#{name}"
define_method("#{name}_decorated") do |*args, &internal_block|
result = nil
internal_method = -> {
result = instance_exec do
send("#{name}_undecorated", *args, &internal_block)
end
}
yield internal_method
result
end
class_eval "alias :#{name} :#{name}_decorated"
end
end
end
end
end
class Bar
Decorator.decorate(self, Foo) do |undecorated|
puts '.' * 50
puts 'Before'
undecorated.call
puts 'After'
end
def bar
'bar'
end
end
b = Bar.new
b.foo_undecorated
x = b.foo
y = b.what(3, 5)
z = b.how(3, 5) { |a, b| a ** b }
puts "return values: #{x}, #{y}, #{z}"
$ ruby test.rb
bar
..................................................
Before
bar
After
..................................................
Before
bar = 3 + 5
After
..................................................
Before
bar: 243
After
42, 42, 42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment