diff --git a/elastic-apm.gemspec b/elastic-apm.gemspec index 530967dd2..367ec7131 100644 --- a/elastic-apm.gemspec +++ b/elastic-apm.gemspec @@ -37,6 +37,7 @@ Gem::Specification.new do |spec| spec.add_dependency('concurrent-ruby', '~> 1.0') spec.add_dependency('http', '>= 3.0') + spec.add_runtime_dependency('ruby2_keywords') spec.require_paths = ['lib'] end diff --git a/lib/elastic_apm.rb b/lib/elastic_apm.rb index 91665d93d..c8eb23ca5 100644 --- a/lib/elastic_apm.rb +++ b/lib/elastic_apm.rb @@ -26,6 +26,7 @@ require 'concurrent' require 'forwardable' require 'securerandom' +require 'ruby2_keywords' require 'elastic_apm/version' require 'elastic_apm/internal_error' diff --git a/lib/elastic_apm/span_helpers.rb b/lib/elastic_apm/span_helpers.rb index a835868ca..2f60db5a8 100644 --- a/lib/elastic_apm/span_helpers.rb +++ b/lib/elastic_apm/span_helpers.rb @@ -37,7 +37,7 @@ def __span_method_on(klass, method, name = nil, type = nil) type ||= Span::DEFAULT_TYPE klass.prepend(Module.new do - define_method(method) do |*args, &block| + ruby2_keywords(define_method(method) do |*args, &block| unless ElasticAPM.current_transaction return super(*args, &block) end @@ -45,7 +45,7 @@ def __span_method_on(klass, method, name = nil, type = nil) ElasticAPM.with_span name.to_s, type.to_s do super(*args, &block) end - end + end) end) end end diff --git a/spec/elastic_apm/span_helpers_spec.rb b/spec/elastic_apm/span_helpers_spec.rb index 4e6009846..8d8583cfa 100644 --- a/spec/elastic_apm/span_helpers_spec.rb +++ b/spec/elastic_apm/span_helpers_spec.rb @@ -38,6 +38,11 @@ def do_the_block_thing(&block) block.call end span_method :do_the_block_thing + + def do_mixed_args_thing(one, two, three: nil) + [one, two, three] + end + span_method :do_mixed_args_thing end context 'on class methods', :intercept do @@ -79,6 +84,19 @@ def do_the_block_thing(&block) expect(@intercepted.spans.length).to be 1 expect(@intercepted.spans.last.name).to eq 'do_the_block_thing' end + + it 'handles mixed positional and keyword arguments' do + thing = Thing.new + + with_agent do + ElasticAPM.with_transaction do + thing.do_mixed_args_thing('one', 'two', three: 'three') + end + end + + expect(@intercepted.spans.length).to be 1 + expect(@intercepted.spans.last.name).to eq 'do_mixed_args_thing' + end end end end