From 8b5983ea71df6040d7196a5f5458f7cf7f04f150 Mon Sep 17 00:00:00 2001 From: Gustavo Caso Date: Tue, 11 Jul 2023 12:24:47 +0200 Subject: [PATCH 1/9] When working on https://github.com/DataDog/dd-trace-rb/pull/2936 I noticed that calling `SafeDup.frozen_or_dup({a: :b})` on ruby 3.2 would break; because it tries to call `+(-){a: :b}` which doesn't work. I had to ensure the `SafeDup` module worked for all objects. I decided to extract that work into a separate PR to ease the work of reviewing. The method `frozen_or_dup` and `frozen_dup` for ruby 2.3 and forward only expect to receive String values. This could lead to future errors. By checking if the value is a String we can warranty the same behaviour for all kinds of objects Also, I added some extract refimients to be able to call `#dup` on `true, false, 1, 1.0` values. --- lib/datadog/core/utils/safe_dup.rb | 60 ++++- spec/datadog/core/utils/safe_dup_spec.rb | 266 ++++++++++++++++++++--- 2 files changed, 287 insertions(+), 39 deletions(-) diff --git a/lib/datadog/core/utils/safe_dup.rb b/lib/datadog/core/utils/safe_dup.rb index 33d20c11998..a31e9651d65 100644 --- a/lib/datadog/core/utils/safe_dup.rb +++ b/lib/datadog/core/utils/safe_dup.rb @@ -13,20 +13,70 @@ def dup end end + # Ensures #initialize can call true.dup safely + module RefineTrue + refine TrueClass do + def dup + self + end + end + end + + # Ensures #initialize can call false.dup safely + module RefineFalse + refine FalseClass do + def dup + self + end + end + end + + # Ensures #initialize can call 1.dup safely + module RefineInteger + refine Integer do + def dup + self + end + end + end + + # Ensures #initialize can call 1.0.dup safely + module RefineFloat + refine Float do + def dup + self + end + end + end + using RefineNil + using RefineTrue + using RefineFalse + using RefineInteger + using RefineFloat end # String#+@ was introduced in Ruby 2.3 if String.method_defined?(:+@) && String.method_defined?(:-@) def self.frozen_or_dup(v) - # If the string is not frozen, the +(-v) will: - # - first create a frozen deduplicated copy with -v - # - then it will dup it more efficiently with +v - v.frozen? ? v : +(-v) + case v + when String + # If the string is not frozen, the +(-v) will: + # - first create a frozen deduplicated copy with -v + # - then it will dup it more efficiently with +v + v.frozen? ? v : +(-v) + else + v.frozen? ? v : v.dup + end end def self.frozen_dup(v) - -v if v + case v + when String + -v if v + else + v.frozen? ? v : v.dup.freeze + end end else def self.frozen_or_dup(v) diff --git a/spec/datadog/core/utils/safe_dup_spec.rb b/spec/datadog/core/utils/safe_dup_spec.rb index d043cd00f00..34b16ef7663 100644 --- a/spec/datadog/core/utils/safe_dup_spec.rb +++ b/spec/datadog/core/utils/safe_dup_spec.rb @@ -1,62 +1,260 @@ require 'datadog/core/utils/safe_dup' RSpec.describe Datadog::Core::Utils::SafeDup do - describe '.frozen_or_dup' do - context 'when given a frozen string' do - it 'returns the original input' do - input = 'a_frozen_string'.freeze + context 'String' do + describe '.frozen_or_dup' do + context 'when given a frozen string' do + it 'returns the original input' do + input = 'a_frozen_string'.freeze - result = described_class.frozen_or_dup(input) + result = described_class.frozen_or_dup(input) - expect(input).to be_frozen + expect(input).to be_frozen - expect(result).to eq(input) - expect(result).to be(input) - expect(result).to be_frozen + expect(result).to eq(input) + expect(result).to be(input) + expect(result).to be_frozen + end + end + + context 'when given a string' do + it 'returns a non frozen dupliacte' do + input = 'a_string' + + result = described_class.frozen_or_dup(input) + + expect(input).not_to be_frozen + + expect(result).to eq(input) + expect(result).not_to be(input) + expect(result).not_to be_frozen + end + end + end + + describe '.frozen_dup' do + context 'when given a frozen string' do + it 'returns the original input' do + input = 'a_frozen_string'.freeze + + result = described_class.frozen_dup(input) + + expect(input).to be_frozen + + expect(result).to eq(input) + expect(result).to be(input) + expect(result).to be_frozen + end + end + + context 'when given a string' do + it 'returns a frozen duplicate' do + input = 'a_string' + + result = described_class.frozen_dup(input) + + expect(input).not_to be_frozen + + expect(result).to eq(input) + expect(result).not_to be(input) + expect(result).to be_frozen + end + end + end + end + + context 'Hash' do + describe '.frozen_or_dup' do + context 'when given a frozen hash' do + it 'returns the original input' do + input = { a: :b }.freeze + + result = described_class.frozen_or_dup(input) + + expect(input).to be_frozen + + expect(result).to eq(input) + expect(result).to be(input) + expect(result).to be_frozen + end + end + + context 'when given a hash' do + it 'returns a non frozen dupliacte' do + input = { a: :b } + + result = described_class.frozen_or_dup(input) + + expect(input).not_to be_frozen + + expect(result).to eq(input) + expect(result).not_to be(input) + expect(result).not_to be_frozen + end end end - context 'when given a string' do - it 'returns a non frozen dupliacte' do - input = 'a_string' + describe '.frozen_dup' do + context 'when given a frozen hash' do + it 'returns the original input' do + input = { a: :b }.freeze + + result = described_class.frozen_dup(input) + + expect(input).to be_frozen + + expect(result).to eq(input) + expect(result).to be(input) + expect(result).to be_frozen + end + end + + context 'when given a hash' do + it 'returns a frozen duplicate' do + input = { a: :b } + + result = described_class.frozen_dup(input) + + expect(input).not_to be_frozen + + expect(result).to eq(input) + expect(result).not_to be(input) + expect(result).to be_frozen + end + end + end + end + + context 'Boolean' do + before do + skip 'TrueClass and FalseClass are not frozen by default on ruby 2.1' if RUBY_VERSION < '2.2' + end + + describe '.frozen_or_dup' do + context 'when given a boolean' do + it 'returns the original input' do + input = true + + result = described_class.frozen_or_dup(input) + + expect(input).to be_frozen + + expect(result).to eq(input) + expect(result).to be(input) + expect(result).to be_frozen + end + end + end + + describe '.frozen_dup' do + context 'when given a boolean' do + it 'returns the original input' do + input = true + + result = described_class.frozen_dup(input) + + expect(input).to be_frozen + + expect(result).to eq(input) + expect(result).to be(input) + expect(result).to be_frozen + end + end + end + end + + context 'Array' do + describe '.frozen_or_dup' do + context 'when given a frozen array' do + it 'returns the original input' do + input = [1].freeze + + result = described_class.frozen_or_dup(input) + + expect(input).to be_frozen + + expect(result).to eq(input) + expect(result).to be(input) + expect(result).to be_frozen + end + end + + context 'when given a string' do + it 'returns a non frozen array' do + input = [1] + + result = described_class.frozen_or_dup(input) + + expect(input).not_to be_frozen + + expect(result).to eq(input) + expect(result).not_to be(input) + expect(result).not_to be_frozen + end + end + end + + describe '.frozen_dup' do + context 'when given a frozen array' do + it 'returns the original input' do + input = [1].freeze + + result = described_class.frozen_dup(input) + + expect(input).to be_frozen + + expect(result).to eq(input) + expect(result).to be(input) + expect(result).to be_frozen + end + end + + context 'when given a array' do + it 'returns a frozen duplicate' do + input = [1] - result = described_class.frozen_or_dup(input) + result = described_class.frozen_dup(input) - expect(input).not_to be_frozen + expect(input).not_to be_frozen - expect(result).to eq(input) - expect(result).not_to be(input) - expect(result).not_to be_frozen + expect(result).to eq(input) + expect(result).not_to be(input) + expect(result).to be_frozen + end end end end - describe '.frozen_dup' do - context 'when given a frozen string' do - it 'returns the original input' do - input = 'a_frozen_string'.freeze + context 'Numeric' do + describe '.frozen_or_dup' do + context 'when given a numeric' do + it 'returns the original input' do + input = 1 - result = described_class.frozen_dup(input) + result = described_class.frozen_or_dup(input) - expect(input).to be_frozen + expect(input).to be_frozen - expect(result).to eq(input) - expect(result).to be(input) - expect(result).to be_frozen + expect(result).to eq(input) + expect(result).to be(input) + expect(result).to be_frozen + end end end - context 'when given a string' do - it 'returns a frozen duplicate' do - input = 'a_string' + describe '.frozen_dup' do + context 'when given a numeric' do + it 'returns the original input' do + input = 10.0 - result = described_class.frozen_dup(input) + result = described_class.frozen_dup(input) - expect(input).not_to be_frozen + expect(input).to be_frozen - expect(result).to eq(input) - expect(result).not_to be(input) - expect(result).to be_frozen + expect(result).to eq(input) + expect(result).to be(input) + expect(result).to be_frozen + end end end end From 6eb117628a266c9bdb7ebe28818448a5d9a8e753 Mon Sep 17 00:00:00 2001 From: Gustavo Caso Date: Wed, 12 Jul 2023 13:19:45 +0200 Subject: [PATCH 2/9] remove duplicate RefineNil module from codebase --- lib/datadog/tracing/span_operation.rb | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/lib/datadog/tracing/span_operation.rb b/lib/datadog/tracing/span_operation.rb index ce371337367..19369e0a62d 100644 --- a/lib/datadog/tracing/span_operation.rb +++ b/lib/datadog/tracing/span_operation.rb @@ -3,6 +3,7 @@ require_relative '../core/environment/identity' require_relative '../core/utils' require_relative '../core/utils/time' +require_relative '../core/utils/safe_dup' require_relative 'event' require_relative 'metadata' @@ -434,19 +435,6 @@ def message :parent, :span - if RUBY_VERSION < '2.2' # nil.dup only fails in Ruby 2.1 - # Ensures #initialize can call nil.dup safely - module RefineNil - refine NilClass do - def dup - self - end - end - end - - using RefineNil - end - # Create a Span from the operation which represents # the finalized measurement. We #dup here to prevent # mutation by reference; when this span is returned, From 08e62e4c6895b906d13756399a4db3ac0367caeb Mon Sep 17 00:00:00 2001 From: Gustavo Caso Date: Wed, 12 Jul 2023 17:06:47 +0200 Subject: [PATCH 3/9] remove dup refinements --- lib/datadog/core/backport.rb | 20 +++++++++ lib/datadog/core/utils/safe_dup.rb | 63 +++------------------------ lib/datadog/tracing/span_operation.rb | 4 +- sig/datadog/core/backport.rbs | 4 ++ 4 files changed, 32 insertions(+), 59 deletions(-) diff --git a/lib/datadog/core/backport.rb b/lib/datadog/core/backport.rb index e80fcd8edab..6fc94b2d556 100644 --- a/lib/datadog/core/backport.rb +++ b/lib/datadog/core/backport.rb @@ -21,5 +21,25 @@ def string_delete_prefix(string, prefix) end end end + + # This module is used to provide features from Ruby 2.4+ to older Rubies + module BackportFrom24 + module_function + + if RUBY_VERSION < '2.4' + def dup(value) + case value + when NilClass, TrueClass, FalseClass, Integer, Float + value + else + value.dup + end + end + else + def dup(value) + value.dup + end + end + end end end diff --git a/lib/datadog/core/utils/safe_dup.rb b/lib/datadog/core/utils/safe_dup.rb index a31e9651d65..340218405e3 100644 --- a/lib/datadog/core/utils/safe_dup.rb +++ b/lib/datadog/core/utils/safe_dup.rb @@ -1,61 +1,10 @@ +require_relative '../backport' + module Datadog module Core module Utils # Helper methods for safer dup module SafeDup - if RUBY_VERSION < '2.2' # nil.dup only fails in Ruby 2.1 - # Ensures #initialize can call nil.dup safely - module RefineNil - refine NilClass do - def dup - self - end - end - end - - # Ensures #initialize can call true.dup safely - module RefineTrue - refine TrueClass do - def dup - self - end - end - end - - # Ensures #initialize can call false.dup safely - module RefineFalse - refine FalseClass do - def dup - self - end - end - end - - # Ensures #initialize can call 1.dup safely - module RefineInteger - refine Integer do - def dup - self - end - end - end - - # Ensures #initialize can call 1.0.dup safely - module RefineFloat - refine Float do - def dup - self - end - end - end - - using RefineNil - using RefineTrue - using RefineFalse - using RefineInteger - using RefineFloat - end - # String#+@ was introduced in Ruby 2.3 if String.method_defined?(:+@) && String.method_defined?(:-@) def self.frozen_or_dup(v) @@ -66,7 +15,7 @@ def self.frozen_or_dup(v) # - then it will dup it more efficiently with +v v.frozen? ? v : +(-v) else - v.frozen? ? v : v.dup + v.frozen? ? v : Core::BackportFrom24.dup(v) end end @@ -75,16 +24,16 @@ def self.frozen_dup(v) when String -v if v else - v.frozen? ? v : v.dup.freeze + v.frozen? ? v : Core::BackportFrom24.dup(v).freeze end end else def self.frozen_or_dup(v) - v.frozen? ? v : v.dup + v.frozen? ? v : Core::BackportFrom24.dup(v) end def self.frozen_dup(v) - v.frozen? ? v : v.dup.freeze + v.frozen? ? v : Core::BackportFrom24.dup(v).freeze end end end diff --git a/lib/datadog/tracing/span_operation.rb b/lib/datadog/tracing/span_operation.rb index 19369e0a62d..27f83d70015 100644 --- a/lib/datadog/tracing/span_operation.rb +++ b/lib/datadog/tracing/span_operation.rb @@ -445,8 +445,8 @@ def build_span duration: duration, end_time: @end_time, id: @id, - meta: meta.dup, - metrics: metrics.dup, + meta: Core::Utils::SafeDup.frozen_or_dup(meta), + metrics: Core::Utils::SafeDup.frozen_or_dup(metrics), parent_id: @parent_id, resource: @resource, service: @service, diff --git a/sig/datadog/core/backport.rbs b/sig/datadog/core/backport.rbs index daa910a53c5..9b3642fe192 100644 --- a/sig/datadog/core/backport.rbs +++ b/sig/datadog/core/backport.rbs @@ -3,5 +3,9 @@ module Datadog module BackportFrom25 def self?.string_delete_prefix: (::String string, ::String prefix) -> ::String end + + module BackportFrom24 + def self?.dup: (untyped value) -> untyped + end end end From f4429a6d9501cc9e20985d92cdd71a0b30a40fa9 Mon Sep 17 00:00:00 2001 From: Gustavo Caso Date: Thu, 13 Jul 2023 09:27:29 +0200 Subject: [PATCH 4/9] Add comment to explain why we have a separate branch for String when using SafeDup --- lib/datadog/core/utils/safe_dup.rb | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/lib/datadog/core/utils/safe_dup.rb b/lib/datadog/core/utils/safe_dup.rb index 340218405e3..dd967237070 100644 --- a/lib/datadog/core/utils/safe_dup.rb +++ b/lib/datadog/core/utils/safe_dup.rb @@ -9,6 +9,11 @@ module SafeDup if String.method_defined?(:+@) && String.method_defined?(:-@) def self.frozen_or_dup(v) case v + # For the case of a String we use the methods +@ and -@. + # Those methods are only for String objects + # they are faster and chepaer on the memory side. + # Check the benchmark on + # https://github.com/DataDog/dd-trace-rb/pull/2704 when String # If the string is not frozen, the +(-v) will: # - first create a frozen deduplicated copy with -v @@ -21,6 +26,11 @@ def self.frozen_or_dup(v) def self.frozen_dup(v) case v + # For the case of a String we use the methods -@ + # That method are only for String objects + # they are faster and chepaer on the memory side. + # Check the benchmark on + # https://github.com/DataDog/dd-trace-rb/pull/2704 when String -v if v else From 1e39d95c5c1101def3148aedea483d187767e7eb Mon Sep 17 00:00:00 2001 From: Gustavo Caso Date: Thu, 13 Jul 2023 12:46:19 +0200 Subject: [PATCH 5/9] improve spec descriptions --- spec/datadog/core/utils/safe_dup_spec.rb | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/spec/datadog/core/utils/safe_dup_spec.rb b/spec/datadog/core/utils/safe_dup_spec.rb index 34b16ef7663..6d7d4f1d8ab 100644 --- a/spec/datadog/core/utils/safe_dup_spec.rb +++ b/spec/datadog/core/utils/safe_dup_spec.rb @@ -11,14 +11,13 @@ expect(input).to be_frozen - expect(result).to eq(input) expect(result).to be(input) expect(result).to be_frozen end end context 'when given a string' do - it 'returns a non frozen dupliacte' do + it 'returns a non-frozen dupliacte' do input = 'a_string' result = described_class.frozen_or_dup(input) @@ -41,7 +40,6 @@ expect(input).to be_frozen - expect(result).to eq(input) expect(result).to be(input) expect(result).to be_frozen end @@ -73,14 +71,13 @@ expect(input).to be_frozen - expect(result).to eq(input) expect(result).to be(input) expect(result).to be_frozen end end context 'when given a hash' do - it 'returns a non frozen dupliacte' do + it 'returns a non-frozen dupliacte' do input = { a: :b } result = described_class.frozen_or_dup(input) @@ -103,7 +100,6 @@ expect(input).to be_frozen - expect(result).to eq(input) expect(result).to be(input) expect(result).to be_frozen end @@ -139,7 +135,6 @@ expect(input).to be_frozen - expect(result).to eq(input) expect(result).to be(input) expect(result).to be_frozen end @@ -155,7 +150,6 @@ expect(input).to be_frozen - expect(result).to eq(input) expect(result).to be(input) expect(result).to be_frozen end @@ -173,14 +167,13 @@ expect(input).to be_frozen - expect(result).to eq(input) expect(result).to be(input) expect(result).to be_frozen end end - context 'when given a string' do - it 'returns a non frozen array' do + context 'when given an array' do + it 'returns a non-frozen copy of that array' do input = [1] result = described_class.frozen_or_dup(input) @@ -203,13 +196,12 @@ expect(input).to be_frozen - expect(result).to eq(input) expect(result).to be(input) expect(result).to be_frozen end end - context 'when given a array' do + context 'when given an array' do it 'returns a frozen duplicate' do input = [1] @@ -235,7 +227,6 @@ expect(input).to be_frozen - expect(result).to eq(input) expect(result).to be(input) expect(result).to be_frozen end @@ -251,7 +242,6 @@ expect(input).to be_frozen - expect(result).to eq(input) expect(result).to be(input) expect(result).to be_frozen end From 368202ebf8c43d85bb5c8aacf2a239b3900bc477 Mon Sep 17 00:00:00 2001 From: Gustavo Caso Date: Thu, 13 Jul 2023 12:47:04 +0200 Subject: [PATCH 6/9] replace swicth case for if..else in SafeDup module --- lib/datadog/core/utils/safe_dup.rb | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/lib/datadog/core/utils/safe_dup.rb b/lib/datadog/core/utils/safe_dup.rb index dd967237070..75fc6bf85a8 100644 --- a/lib/datadog/core/utils/safe_dup.rb +++ b/lib/datadog/core/utils/safe_dup.rb @@ -8,13 +8,12 @@ module SafeDup # String#+@ was introduced in Ruby 2.3 if String.method_defined?(:+@) && String.method_defined?(:-@) def self.frozen_or_dup(v) - case v # For the case of a String we use the methods +@ and -@. # Those methods are only for String objects # they are faster and chepaer on the memory side. # Check the benchmark on # https://github.com/DataDog/dd-trace-rb/pull/2704 - when String + if v === String # If the string is not frozen, the +(-v) will: # - first create a frozen deduplicated copy with -v # - then it will dup it more efficiently with +v @@ -25,13 +24,12 @@ def self.frozen_or_dup(v) end def self.frozen_dup(v) - case v # For the case of a String we use the methods -@ # That method are only for String objects # they are faster and chepaer on the memory side. # Check the benchmark on # https://github.com/DataDog/dd-trace-rb/pull/2704 - when String + if v === String -v if v else v.frozen? ? v : Core::BackportFrom24.dup(v).freeze From 20f315bffcae18cf1da060e6a43e3b4022cfee2e Mon Sep 17 00:00:00 2001 From: Gustavo Caso Date: Thu, 13 Jul 2023 12:48:30 +0200 Subject: [PATCH 7/9] remove module_function from Backport modules --- lib/datadog/core/backport.rb | 12 ++++-------- sig/datadog/core/backport.rbs | 4 ++-- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/lib/datadog/core/backport.rb b/lib/datadog/core/backport.rb index 6fc94b2d556..8cc67cfbfb1 100644 --- a/lib/datadog/core/backport.rb +++ b/lib/datadog/core/backport.rb @@ -4,14 +4,12 @@ module Datadog module Core # This module is used to provide features from Ruby 2.5+ to older Rubies module BackportFrom25 - module_function - if ::String.method_defined?(:delete_prefix) - def string_delete_prefix(string, prefix) + def self.string_delete_prefix(string, prefix) string.delete_prefix(prefix) end else - def string_delete_prefix(string, prefix) + def self.string_delete_prefix(string, prefix) prefix = prefix.to_s if string.start_with?(prefix) string[prefix.length..-1] || raise('rbs-guard: String#[] is non-nil as `prefix` is guaranteed present') @@ -24,10 +22,8 @@ def string_delete_prefix(string, prefix) # This module is used to provide features from Ruby 2.4+ to older Rubies module BackportFrom24 - module_function - if RUBY_VERSION < '2.4' - def dup(value) + def self.dup(value) case value when NilClass, TrueClass, FalseClass, Integer, Float value @@ -36,7 +32,7 @@ def dup(value) end end else - def dup(value) + def self.dup(value) value.dup end end diff --git a/sig/datadog/core/backport.rbs b/sig/datadog/core/backport.rbs index 9b3642fe192..586e6fa58d3 100644 --- a/sig/datadog/core/backport.rbs +++ b/sig/datadog/core/backport.rbs @@ -1,11 +1,11 @@ module Datadog module Core module BackportFrom25 - def self?.string_delete_prefix: (::String string, ::String prefix) -> ::String + def self.string_delete_prefix: (::String string, ::String prefix) -> ::String end module BackportFrom24 - def self?.dup: (untyped value) -> untyped + def self.dup: (Object value) -> Object end end end From be7e099469d2345f0c668d06f9b2b83a24c06f43 Mon Sep 17 00:00:00 2001 From: Gustavo Caso Date: Thu, 13 Jul 2023 12:49:01 +0200 Subject: [PATCH 8/9] Add backport support for dup for Bignum and Fixnum --- lib/datadog/core/backport.rb | 4 +++- sig/datadog/core/backport.rbs | 3 +++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/datadog/core/backport.rb b/lib/datadog/core/backport.rb index 8cc67cfbfb1..5ef4334a552 100644 --- a/lib/datadog/core/backport.rb +++ b/lib/datadog/core/backport.rb @@ -23,14 +23,16 @@ def self.string_delete_prefix(string, prefix) # This module is used to provide features from Ruby 2.4+ to older Rubies module BackportFrom24 if RUBY_VERSION < '2.4' + # rubocop:disable Lint/UnifiedInteger def self.dup(value) case value - when NilClass, TrueClass, FalseClass, Integer, Float + when NilClass, TrueClass, FalseClass, Integer, Float, Bignum, Fixnum value else value.dup end end + # rubocop:enable Lint/UnifiedInteger else def self.dup(value) value.dup diff --git a/sig/datadog/core/backport.rbs b/sig/datadog/core/backport.rbs index 586e6fa58d3..186d416e903 100644 --- a/sig/datadog/core/backport.rbs +++ b/sig/datadog/core/backport.rbs @@ -5,6 +5,9 @@ module Datadog end module BackportFrom24 + Fixnum: Integer + Bignum: Integer + def self.dup: (Object value) -> Object end end From d832464ad5cb29e07813123aa02a7256ea229427 Mon Sep 17 00:00:00 2001 From: Gustavo Caso Date: Thu, 13 Jul 2023 13:31:25 +0200 Subject: [PATCH 9/9] apply feedback --- lib/datadog/core/backport.rb | 4 +--- lib/datadog/core/utils/safe_dup.rb | 4 ++-- sig/datadog/core/backport.rbs | 3 --- 3 files changed, 3 insertions(+), 8 deletions(-) diff --git a/lib/datadog/core/backport.rb b/lib/datadog/core/backport.rb index 5ef4334a552..88a36f3a1ff 100644 --- a/lib/datadog/core/backport.rb +++ b/lib/datadog/core/backport.rb @@ -23,16 +23,14 @@ def self.string_delete_prefix(string, prefix) # This module is used to provide features from Ruby 2.4+ to older Rubies module BackportFrom24 if RUBY_VERSION < '2.4' - # rubocop:disable Lint/UnifiedInteger def self.dup(value) case value - when NilClass, TrueClass, FalseClass, Integer, Float, Bignum, Fixnum + when NilClass, TrueClass, FalseClass, Numeric value else value.dup end end - # rubocop:enable Lint/UnifiedInteger else def self.dup(value) value.dup diff --git a/lib/datadog/core/utils/safe_dup.rb b/lib/datadog/core/utils/safe_dup.rb index 75fc6bf85a8..5d74cdb2ac1 100644 --- a/lib/datadog/core/utils/safe_dup.rb +++ b/lib/datadog/core/utils/safe_dup.rb @@ -13,7 +13,7 @@ def self.frozen_or_dup(v) # they are faster and chepaer on the memory side. # Check the benchmark on # https://github.com/DataDog/dd-trace-rb/pull/2704 - if v === String + if v.is_a?(String) # If the string is not frozen, the +(-v) will: # - first create a frozen deduplicated copy with -v # - then it will dup it more efficiently with +v @@ -29,7 +29,7 @@ def self.frozen_dup(v) # they are faster and chepaer on the memory side. # Check the benchmark on # https://github.com/DataDog/dd-trace-rb/pull/2704 - if v === String + if v.is_a?(String) -v if v else v.frozen? ? v : Core::BackportFrom24.dup(v).freeze diff --git a/sig/datadog/core/backport.rbs b/sig/datadog/core/backport.rbs index 186d416e903..586e6fa58d3 100644 --- a/sig/datadog/core/backport.rbs +++ b/sig/datadog/core/backport.rbs @@ -5,9 +5,6 @@ module Datadog end module BackportFrom24 - Fixnum: Integer - Bignum: Integer - def self.dup: (Object value) -> Object end end