rubocop-performance icon indicating copy to clipboard operation
rubocop-performance copied to clipboard

Edge case for StringReplacement: Use delete instead of gsub cop

Open MatzFan opened this issue 10 months ago • 1 comments

Expected behavior

Using gsub instead of delete for integers expressed as unicode characters should trigger this offense

Actual behavior

No offense is registered

Steps to reproduce the problem

str.gsub(8203.chr('UTF-8'),'') # should register offense and suggest use of delete

RuboCop version

1.56.4 (using Parser 3.2.2.3, rubocop-ast 1.29.0, running on ruby 3.2.2) [x86_64-linux]                                                       
  - rubocop-capybara 2.18.0                                          
  - rubocop-minitest 0.31.1                                          
  - rubocop-performance 1.19.1                                       
  - rubocop-rake 0.6.0                                               
  - rubocop-sequel 0.3.4

There may also be unicode character substitution edge cases in the gsub vs. tr version of this cop too.

MatzFan avatar Oct 08 '23 21:10 MatzFan

FWIW it is possible to match the two forms of integer coercion to an encoded character string using Integer#chr with a mere 103 regexps.

str = '55_295.chr(Encoding::UTF-8)'
str1 = "0.chr('ASCII-8BIT')"

int_to_char_encoding_regexps = Encoding.list.map { |enc| /\d{0,2}_?\d{1,3}\.chr\((Encoding::)?'?#{Regexp.quote(enc.to_s)}'?\)/ }

puts int_to_char_encoding_regexps.any? { |r| r.match? str } # => true
puts int_to_char_encoding_regexps.any? { |r| r.match? str1 } # => true

I'm sure there's a more elegant way.

MatzFan avatar Oct 10 '23 03:10 MatzFan