AfterDo::Loader

after_do-loader is a gem that allows you to apply after_do's callbacks dynamically using a config file. With this, you do need to add anything to your source code, much like aspect oriented programming does.

Installation

Add this line to your application's Gemfile:

gem 'after_do-loader'

And then execute:

$ bundle

Or install it yourself as:

$ gem install after_do-loader

Usage

In order to use this gem, you need to add a aspects.yml file to your application. This file must define the classes that will implement the callbacks used by after_do's methods.

Example:

Suppose I want to log every method call to AdvisedClass#initialize, before and after it's invocation. What will be logged is defined in the LoggingAspect#log_start and LoggingAspect#log_finish methods.

The aspects.yml file must look like this:

aspects:
  - name: Logging
    klass: LoggingAspect
    description: This aspects provides basic method logging
    advices:
      - names: [log_start, log_finish]
        targets:
          - klass: AdvisedClass
            target_methods:
              - initialize
              - merge
          - klass: AdvisedClass > # Matches all AdvisedClass' subclasses
            target_methods:
              - initialize
              - merge

And the LoggingAspect class will be something like this:

class LoggingAspect
  def initialize(target_class)
    @target_class = target_class
  end

  def log_start(target_method)
    target_class.before target_method do |*args, advised_class_instance|
      init_time = Time.now
      arg_text = args.map(&:inspect).join(', ')
      method = "#{target_class}##{target_method}"

      msg = "Started: Method=#{method} Time=#{init_time} Args='#{arg_text}'"
      Rails.logger.info(msg)
    end
  end

  def log_finish(target_method)
    target_class.after target_method do |*args, advised_class_instance|
      init_time = Time.now
      arg_text = args.map(&:inspect).join(', ')
      method = "#{target_class}##{target_method}"

      msg = "Finished: Method=#{method} Time=#{init_time} Args='#{arg_text}'"

      Rails.logger.info(msg)
    end
  end

  private

  attr_reader :target_class
end

In order to load the aspects.yml and apply LoggingAspect#log_start and LoggingAspect#log_finish, you need to add to call the AfterDo::Loader.load method passing the configuration file path. In a rails app, this would be something like the following:

AfterDo::Loader.load(Rails.root.join('config', 'aspects.yml'))

Contributing

  1. Fork it ( https://github.com/rranelli/after_do-loader/fork )
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create a new Pull Request