Let's create a module that with a method that can wrap around another.

module Wrappable
def log(name)
original_method = instance_method(name)
define_method(name) do |*args|
puts "Calling #{name} with #{args.inspect}."
result = original_method.bind(self).call(*args)
puts "Completed #{name}."
result
end
end
end

Now, let's create a class where we are particularly interested in wrapping one of the methods.

class Foo
extend Wrappable

log def add(item)
@stuff ||=[]
@stuff << item
end
end

Notice the log before the method declaration?

Foo.new.add('Bananas')
# Calling add with ["Bananas"].
# Completed add.
# => ["Bananas"]