class Delfos::Patching::MethodOverride

Constants

META_PROGRAMMING_REGEX

Attributes

class_method[R]
klass[R]
name[R]
private_methods[R]

Public Class Methods

new(klass, name, private_methods, class_method) click to toggle source
# File lib/delfos/patching/method_override.rb, line 53
def initialize(klass, name, private_methods, class_method)
  @klass           = klass
  @name            = name
  @private_methods = private_methods
  @class_method    = class_method
  original_method # ensure memoized method is the original not the overridden one
end
setup(klass, name, private_methods, class_method:) click to toggle source
# File lib/delfos/patching/method_override.rb, line 17
def setup(klass, name, private_methods, class_method:)
  return if skip_meta_programming_defined_method?

  MUTEX.synchronize do
    return if Thread.current[:__delfos_disable_patching]
  end

  instance = new(klass, name, private_methods, class_method)

  instance.ensure_method_recorded_once!
end
skip_meta_programming_defined_method?() click to toggle source
# File lib/delfos/patching/method_override.rb, line 31
def skip_meta_programming_defined_method?
  stack = caller.dup

  i = stack.index do |l|
    l["delfos/patching/basic_object.rb"]
  end

  return unless i

  result = stack[i + 1][META_PROGRAMMING_REGEX]

  return unless result

  Delfos.logger.debug "Skipping setting up delfos logging of method defined by #{result} #{stack[i+1]}"
  true
end

Public Instance Methods

ensure_method_recorded_once!() click to toggle source
# File lib/delfos/patching/method_override.rb, line 61
def ensure_method_recorded_once!
  record_method! { setup }
end
original_method() click to toggle source
# File lib/delfos/patching/method_override.rb, line 114
def original_method
  @original_method ||= if class_method
                         klass.method(name)
                       else
                         klass.instance_method(name)
                       end
end
setup() click to toggle source

Redefine the method at runtime to enabling logging to Neo4j

Calls superclass method
# File lib/delfos/patching/method_override.rb, line 67
def setup
  cm = class_method
  with_stack = method(:with_stack)
  method_name = name
  om = original_method

  mod = module_definition(klass, name, class_method) do
    define_method(method_name) do |*args, **kw_args, &block|
      stack = caller.dup
      caller_binding = binding.dup
      parameters = Delfos::MethodLogging::MethodParameters.new(args, kw_args, block)

      call_site = Delfos::MethodLogging::CodeLocation.from_call_site(stack, caller_binding)

      if call_site
        Delfos::MethodLogging.log(call_site, self, om, cm, parameters)
      end

      with_stack.call(call_site) do
        if !kw_args.empty?
          super(*args, **kw_args, &block)
        else
          super(*args, &block)
        end
      end
    end
  end
  return unless mod

  if class_method
    klass.prepend mod
  else
    klass.instance_eval { prepend mod }
  end
end
with_stack(call_site) { || ... } click to toggle source
# File lib/delfos/patching/method_override.rb, line 103
def with_stack(call_site)
  return yield unless call_site

  begin
    CallStack.push(call_site)
    yield
  ensure
    CallStack.pop
  end
end

Private Instance Methods

bail?() click to toggle source
# File lib/delfos/patching/method_override.rb, line 131
def bail?
  method_has_been_added? || private_method? || exclude?
end
exclude?() click to toggle source
# File lib/delfos/patching/method_override.rb, line 143
def exclude?
  ::Delfos::MethodLogging.exclude?(original_method)
end
method_has_been_added?() click to toggle source
# File lib/delfos/patching/method_override.rb, line 135
def method_has_been_added?
  MethodCache.find(klass: klass, class_method: class_method, method_name: name)
end
private_method?() click to toggle source
# File lib/delfos/patching/method_override.rb, line 139
def private_method?
  private_methods.include?(name.to_sym)
end
record_method!() { || ... } click to toggle source
# File lib/delfos/patching/method_override.rb, line 124
def record_method!
  return true if bail?
  MethodCache.append(klass: klass, method: original_method)

  yield
end