Provides an easy way to define decorations that add common behaviour to your methods.
gem install decoratable
Decoratable does its magic via Module#prepend, which means:
-
MRI (1.9.3 and up) OR
-
JRuby 9000
require "decoratable" module Retryable # All methods defined in this module can decorate methods extend Decoratable def retryable(tries = 1, options = { on: [RuntimeError] }) attempt = 0 # To invoke the original method, simply use `yield` yield rescue *options[:on] attempt += 1 attempt > tries ? raise : retry end end module Pryable extend Decoratable def pryable yield rescue => e require "pry" binding.pry end end module Measurable extend Decoratable def measurable(logger = Logger.new(STDOUT)) start = Time.now yield ensure # The decoration has access to the original method # args and any block passed in the original method call are also available # via __args__ and __block__ respectively original_method = __decorated_method__ method_location, line = original_method.source_location marker = "#{original_method.owner}##{original_method.name}[#{method_location}:#{line}]" duration = (Time.now - start).round(2) logger.info "#{marker} took #{duration}s to run." end end class Client extend Measurable extend Pryable extend Retryable # This method will automatically retry on TimeoutErrors, up to 3 times retryable(tries = 3, on: [TimeoutError]) def get … end # If an error is raised in this method, we'll automatically get a pry session # to help us debug it pryable def post … end # Log the time this method takes to run measurable def delete … end end
Decoratable provides a handful of decorations as part of the gem:
* require "decoratable/countable": keep a count each time a method gets called * require "decoratable/debuggable": open a Ruby debug console (i.e. require "debug") if an error is raised * require "decoratable/deprecatable": log a warning whenever a deprecated method gets called; logs the caller's location * require "decoratable/hintable": add type hinting to your method arguments * require "decoratable/memoizable": automatically memoize the return value of a method * require "decoratable/pryable": open a Pry debug console (i.e. binding.pry) if an error is raised * require "decoratable/retryable": automatically retry a number of times when a specified exception is raised * require "decoratable/synchronizable": only allow a method to be called once at a time
More to be added as time goes on.