lib/appmap/hook/method.rb in appmap-0.73.0 vs lib/appmap/hook/method.rb in appmap-0.74.0
- old
+ new
@@ -67,32 +67,28 @@
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_method_def = Proc.new do |*args, &block|
- is_array_containing_empty_hash = ->(obj) {
- obj.is_a?(Array) && obj.length == 1 && obj[0].is_a?(Hash) && obj[0].size == 0
- }
+ is_array_containing_empty_hash = ->(obj) {
+ obj.is_a?(Array) && obj.length == 1 && obj[0].is_a?(Hash) && obj[0].size == 0
+ }
- call_instance_method = -> {
- # https://github.com/applandinc/appmap-ruby/issues/153
- if NEW_RUBY && is_array_containing_empty_hash.(args) && hook_method.arity == 1
- if NEW_RUBY
- hook_method.bind_call(self, {}, &block)
- else
- hook_method.bind(self).call({}, &block)
- end
+ call_instance_method = lambda do |receiver, args, &block|
+ # https://github.com/applandinc/appmap-ruby/issues/153
+ if NEW_RUBY && is_array_containing_empty_hash.(args) && hook_method.arity == 1
+ hook_method.bind_call(receiver, {}, &block)
+ else
+ if NEW_RUBY
+ hook_method.bind_call(receiver, *args, &block)
else
- if NEW_RUBY
- hook_method.bind_call(self, *args, &block)
- else
- hook_method.bind(self).call(*args, &block)
- end
+ hook_method.bind(receiver).call(*args, &block)
end
- }
+ end
+ end
+ hook_method_def = Proc.new do |*args, &block|
# 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
@@ -100,19 +96,21 @@
disabled_by_shallow_flag = \
-> { hook_package&.shallow? && AppMap.tracing.last_package_for_current_thread == hook_package }
enabled = true if AppMap.tracing.enabled? && !reentrant && !disabled_by_shallow_flag.call
- return call_instance_method.call unless enabled
+ enabled = false if %i[instance_eval instance_exec].member?(hook_method.name) && args.empty?
+ return call_instance_method.call(self, args, &block) unless enabled
+
call_event, start_time = with_disabled_hook.call do
before_hook.call(self, defined_class, args)
end
return_value = nil
exception = nil
begin
- return_value = call_instance_method.call
+ return_value = call_instance_method.call(self, args, &block)
rescue
exception = $ERROR_INFO
raise
ensure
with_disabled_hook.call do
@@ -123,11 +121,21 @@
hook_method_def = hook_method_def.ruby2_keywords if hook_method_def.respond_to?(:ruby2_keywords)
hook_method_parameters = hook_method.parameters.dup.freeze
SIGNATURES[[ hook_class, hook_method.name ]] = hook_method_parameters
- hook_class.ancestors.first.tap do |cls|
- cls.define_method_with_arity(hook_method.name, hook_method.arity, hook_method_def)
+ # irb(main):001:0> Kernel.public_instance_method(:system)
+ # (irb):1:in `public_instance_method': method `system' for module `Kernel' is private (NameError)
+ if hook_class == Kernel
+ hook_class.define_method_with_arity(hook_method.name, hook_method.arity, hook_method_def)
+ else
+ hook_class.ancestors.find { |cls| cls.method_defined?(hook_method.name, false) }.tap do |cls|
+ if cls
+ cls.define_method_with_arity(hook_method.name, hook_method.arity, hook_method_def)
+ else
+ warn "#{hook_method.name} not found on #{hook_class}"
+ end
+ end
end
end
protected