lib/appmap/hook/method.rb in appmap-0.34.1 vs lib/appmap/hook/method.rb in appmap-0.34.2

- old
+ new

@@ -1,10 +1,15 @@ module AppMap class Hook class Method - attr_reader :hook_class, :hook_method, :defined_class, :method_display_name + attr_reader :hook_class, :hook_method + # +method_display_name+ may be nil if name resolution gets + # deferred until runtime (e.g. for a singleton method on an + # embedded Struct). + attr_reader :method_display_name + HOOK_DISABLE_KEY = 'AppMap::Hook.disable' private_constant :HOOK_DISABLE_KEY # Grab the definition of Time.now here, to avoid interfering # with the method we're hooking. @@ -12,31 +17,46 @@ private_constant :TIME_NOW def initialize(hook_class, hook_method) @hook_class = hook_class @hook_method = hook_method + + # Get the class for the method, if it's known. @defined_class, method_symbol = Hook.qualify_method_name(@hook_method) - @method_display_name = [@defined_class, method_symbol, @hook_method.name].join + @method_display_name = [@defined_class, method_symbol, @hook_method.name].join if @defined_class end def activate - warn "AppMap: Hooking #{method_display_name}" if Hook::LOG + if Hook::LOG + msg = if method_display_name + "#{method_display_name}" + else + "#{hook_method.name} (class resolution deferrred)" + end + warn "AppMap: Hooking " + msg + end + defined_class = @defined_class hook_method = self.hook_method before_hook = self.method(:before_hook) after_hook = self.method(:after_hook) with_disabled_hook = self.method(:with_disabled_hook) hook_class.define_method hook_method.name do |*args, &block| instance_method = hook_method.bind(self).to_proc + # We may not have gotten the class for the method during + # initialization (e.g. for a singleton method on an embedded + # struct), so make sure we have it now. + defined_class,_ = Hook.qualify_method_name(hook_method) unless defined_class + hook_disabled = Thread.current[HOOK_DISABLE_KEY] enabled = true if !hook_disabled && AppMap.tracing.enabled? return instance_method.call(*args, &block) unless enabled call_event, start_time = with_disabled_hook.() do - before_hook.(self, args) + before_hook.(self, defined_class, args) end return_value = nil exception = nil begin return_value = instance_method.(*args, &block) @@ -51,10 +71,10 @@ end end protected - def before_hook(receiver, args) + def before_hook(receiver, defined_class, args) require 'appmap/event' call_event = AppMap::Event::MethodCall.build_from_invocation(defined_class, hook_method, receiver, args) AppMap.tracing.record_event call_event, defined_class: defined_class, method: hook_method [ call_event, TIME_NOW.call ] end