class MethodFound::Interceptor

Class for intercepting method calls using method_missing. Initialized by passing in a matcher object which can be a Regexp, a proc or lambda, or a string/symbol.

Attributes

matcher[R]

Public Class Methods

new(matcher = nil, &intercept_block) click to toggle source

Creates an interceptor module to include into a class. @param (see define_method_missing)

# File lib/method_found/interceptor.rb, line 14
def initialize(matcher = nil, &intercept_block)
  define_method_missing(matcher, &intercept_block) unless matcher.nil?
end

Public Instance Methods

define_method_missing(matcher, &intercept_block) click to toggle source

Define method_missing and respond_to_missing? on this interceptor. Can be called after interceptor has been created. @param [Regexp,Proc,String,Symbol] matcher Matcher for intercepting

method calls.

@yield [method_name, matches, &block] Yiels method_name matched, set of

matches returned from matcher, and block passed to method when called.
Calls superclass method
# File lib/method_found/interceptor.rb, line 24
def define_method_missing(matcher, &intercept_block)
  @matcher = matcher_ = Matcher.new(matcher)
  assign_intercept_method(&intercept_block)
  method_cacher = method(:cache_method)

  define_method :method_missing do |method_name, *arguments, &method_block|
    if matches = matcher_.match(method_name, self)
      method_cacher.(method_name, matches)
      send(method_name, *arguments, &method_block)
    else
      super(method_name, *arguments, &method_block)
    end
  end

  define_method :respond_to_missing? do |method_name, include_private = false|
    if matches = matcher_.match(method_name, self)
      method_cacher.(method_name, matches)
    else
      super(method_name, include_private)
    end
  end
end
inspect() click to toggle source
# File lib/method_found/interceptor.rb, line 47
def inspect
  klass = self.class
  name  = klass.name || klass.inspect
  "#<#{name}: #{matcher.inspect}>"
end

Private Instance Methods

assign_intercept_method(&intercept_block) click to toggle source
# File lib/method_found/interceptor.rb, line 66
def assign_intercept_method(&intercept_block)
  @intercept_method ||= "__intercept_#{SecureRandom.hex}".freeze.tap do |method_name|
    define_method method_name, &intercept_block
  end
end
cache_method(method_name, matches) click to toggle source
Calls superclass method
# File lib/method_found/interceptor.rb, line 55
def cache_method(method_name, matches)
  intercept_method, matcher = @intercept_method, @matcher
  define_method method_name do |*arguments, &block|
    if matcher.proc? && !(matches = matcher.match(method_name, self))
      return super(*arguments, &block)
    end
    arguments = [matches, *arguments] unless method(intercept_method).arity == 1
    send(intercept_method, method_name, *arguments, &block)
  end
end