Sha256: fe292ca8b6e980db06924f3e721fbd54661f95078b9607dda57f2c3857a86095

Contents?: true

Size: 1.87 KB

Versions: 1

Compression:

Stored size: 1.87 KB

Contents

class MethodObserver

  VERSION = '0.0.1'

  @before = ->(klass, target, method, *args, &block) {}
  @after  = ->(klass, target, method, *args, &block) {}
  @around = ->(klass, target, method, *args, &block) { block.call }

  class << self

    alias_method :configure, :tap

    def before(&block)
      @before = block
    end
    
    def after(&block)
      @after = block
    end
    
    def around(&block)
      @around = block
    end

    def observe(klass, options)
      options.fetch(:instance, []).each do |method|
        observe_instance_method klass, method
      end

      options.fetch(:class, []).each do |method|
        observe_class_method klass, method
      end
    end

    private

    def observe_instance_method(klass, method)
      observe_before = @before
      observe_after  = @after
      observe_around = @around

      observed_method = "__#{method}_observed__"
      klass.send :alias_method, observed_method, method
      
      klass.send(:define_method, method) do |*args, &block|
        observe_before.call klass, :instance, method, args
        result = observe_around.call klass, :instance, method, args do
          send observed_method, *args, &block
        end
        observe_after.call klass, :instance, method, args
        result
      end
    end

    def observe_class_method(klass, method)
      observe_before = @before
      observe_after  = @after
      observe_around = @around

      observed_method = "__#{method}_observed__"
      klass.singleton_class.send :alias_method, observed_method, method
      
      klass.send(:define_singleton_method, method) do |*args, &block|
        observe_before.call klass, :class, method, args
        result = observe_around.call klass, :class, method, args do
          send observed_method, *args, &block
        end
        observe_after.call klass, :class, method, args
        result
      end
    end

  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
method_observer-0.0.1 lib/method_observer.rb