Decoratable
Provides an easy way to define decorations that add common behaviour to your methods.
Installation
gem install decoratable
Requirements
Decoratable does its magic via Module#prepend, which means:
-
MRI (1.9.3 and up) OR
-
JRuby 9000
Usage
require "decoratable"
module Retryable
# All methods defined in this module can decorate methods
extend Decoratable
def retryable(tries = 1, = { on: [RuntimeError] })
attempt = 0
# To invoke the original method, simply use `yield`
yield
rescue *[: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.