Ruby prepend wrappers
Imagine we have some sort of object (which we don’t own) and we’d like to audit it. You could write an explicit wrapper around the object to audit it, but then you’ve got to keep in mind that you have to use this wrapper whenever you use the service.
You can add new functionality, whilst preserving the old interface and function like this:
class Foo # class we do not own
def bar(arg)
sleep arg
"Running bar with #{arg}!"
end
end
module FooWrapper
def bar(arg)
start_time = Time.now
result = super
time_taken = Time.now - start_time
puts "bar() took more than #{time_taken} seconds" if 2 < time_taken
result
rescue
"bar() failed"
end
end
Foo.class_eval do
prepend FooWrapper
end
Foo.new.bar 2.5
# bar() took more than 2.501257 seconds
# => "Running bar with 2.5!"
We’ve created a wrapper, opened up the class and prepended the wrapper. The wrapper adds new functionality, whilst preserving the old.
The downside to this approach is that whenever you call Foo#bar
, you will get your added functionality each time. This may, or may not, be an issue depending your circumstance.