Sha256: b2ccdcc7c300de704148c057e4f7b951ee14494ce13659ad0e99d5d7fbbe0f63

Contents?: true

Size: 1.68 KB

Versions: 2

Compression:

Stored size: 1.68 KB

Contents

# frozen_string_literal: true

# in some class
#   def self.before(proc=nil, &block)
#     BeforeAndAfter.add(self, caller[0], :before, proc || block)
#   end
# or
#   BeforeAndAfter.define self, :before, :after
#
# then to execute
# instance_object = SomeClass.new
# BeforeAndAfter.execute(instance_object, :before)
# or
# before do
#   ...
# end
# or
# def before
#   super
#   ...
# end
#
# logic is very simple, keep all pointers to all blocks in one class, resolve and execute as needed
# we keep methods and ponters in different hashes to allow hot reload while development

module BeforeAndAfter
  extend self

  @@methods  = {}
  @@pointers = {}

  def add(klass, unique_id, action, method)
    key = Crypt.md5(unique_id)
    @@pointers[key] = method
    @@methods[klass.to_s] ||= {}
    @@methods[klass.to_s][action] ||= []
    @@methods[klass.to_s][action].push(key) unless @@methods[klass.to_s][action].index(key)
  end

  def execute(instance_object, action)
    instance_object.send(action)

    # execute for self and parent
    for name in instance_object.class.ancestors.reverse.map(&:to_s)
      next if name == 'Object'

      if @@methods[name] && @@methods[name][action]
        for el in @@methods[name][action].map { |o| @@pointers[o] }
          if el.kind_of?(Symbol)
            instance_object.send(el)
          else
            instance_object.instance_exec &el
          end
        end
      end
    end
  end

  def define(klass, *args)
    for action in args
      klass.class_eval %[
        def #{action}
        end

        def self.#{action}(proc=nil, opts={}, &block)
          BeforeAndAfter.add(self, caller[0], :#{action}, proc || block)
        end
      ]
    end
  end
end

Version data entries

2 entries across 2 versions & 1 rubygems

Version Path
lux-fw-0.1.35 ./lib/common/before_and_after.rb
lux-fw-0.1.17 ./lib/common/before_and_after.rb