Skip to content

Commit 8c368f6

Browse files
committed
[Fix #492] Fix false positives for Performance/StringIdentifierArgument
This PR fixes false positives for `Performance/StringIdentifierArgument` when using interpolated string argument. Converting a string with interpolation into a symbol degrades performance. Fixes #492.
1 parent d842831 commit 8c368f6

File tree

3 files changed

+18
-32
lines changed

3 files changed

+18
-32
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
* [#492](https://github.com/rubocop/rubocop-performance/issues/492): Fix false positives for `Performance/StringIdentifierArgument` when using interpolated string argument. ([@koic][])

lib/rubocop/cop/performance/string_identifier_argument.rb

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,19 +16,19 @@ module Performance
1616
# send('do_something')
1717
# attr_accessor 'do_something'
1818
# instance_variable_get('@ivar')
19-
# respond_to?("string_#{interpolation}")
2019
#
2120
# # good
2221
# send(:do_something)
2322
# attr_accessor :do_something
2423
# instance_variable_get(:@ivar)
25-
# respond_to?(:"string_#{interpolation}")
2624
#
2725
# # good - these methods don't support namespaced symbols
2826
# const_get("#{module_path}::Base")
2927
# const_source_location("#{module_path}::Base")
3028
# const_defined?("#{module_path}::Base")
3129
#
30+
# # good - using a symbol when string interpolation is involved causes a performance regression.
31+
# respond_to?("string_#{interpolation}")
3232
#
3333
class StringIdentifierArgument < Base
3434
extend AutoCorrector
@@ -40,8 +40,6 @@ class StringIdentifierArgument < Base
4040
protected public public_constant module_function
4141
].freeze
4242

43-
INTERPOLATION_IGNORE_METHODS = %i[const_get const_source_location const_defined?].freeze
44-
4543
TWO_ARGUMENTS_METHOD = :alias_method
4644
MULTIPLE_ARGUMENTS_METHODS = %i[
4745
attr_accessor attr_reader attr_writer private private_constant
@@ -59,7 +57,7 @@ class StringIdentifierArgument < Base
5957
deprecate_constant remove_const ruby2_keywords define_singleton_method instance_variable_defined?
6058
instance_variable_get instance_variable_set method public_method public_send remove_instance_variable
6159
respond_to? send singleton_method __send__
62-
] + COMMAND_METHODS + INTERPOLATION_IGNORE_METHODS).freeze
60+
] + COMMAND_METHODS).freeze
6361

6462
def on_send(node)
6563
return if COMMAND_METHODS.include?(node.method_name) && node.receiver
@@ -83,13 +81,7 @@ def string_arguments(node)
8381
[node.first_argument]
8482
end
8583

86-
arguments.compact.filter { |argument| string_argument_compatible?(argument, node) }
87-
end
88-
89-
def string_argument_compatible?(argument, node)
90-
return true if argument.str_type?
91-
92-
argument.dstr_type? && INTERPOLATION_IGNORE_METHODS.none? { |method| node.method?(method) }
84+
arguments.compact.filter(&:str_type?)
9385
end
9486

9587
def register_offense(argument, argument_value)

spec/rubocop/cop/performance/string_identifier_argument_spec.rb

Lines changed: 13 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -44,26 +44,19 @@
4444
RUBY
4545
end
4646

47-
if described_class::INTERPOLATION_IGNORE_METHODS.include?(method)
48-
it 'does not register an offense when using string interpolation for `#{method}` method' do
49-
# NOTE: These methods don't support `::` when passing a symbol. const_get('A::B') is valid
50-
# but const_get(:'A::B') isn't. Since interpolated arguments may contain any content these
51-
# cases are not detected as an offense to prevent false positives.
52-
expect_no_offenses(<<~RUBY)
53-
#{method}("\#{module_name}class_name")
54-
RUBY
55-
end
56-
else
57-
it 'registers an offense when using interpolated string argument' do
58-
expect_offense(<<~RUBY, method: method)
59-
#{method}("do_something_\#{var}")
60-
_{method} ^^^^^^^^^^^^^^^^^^^^^ Use `:"do_something_\#{var}"` instead of `"do_something_\#{var}"`.
61-
RUBY
62-
63-
expect_correction(<<~RUBY)
64-
#{method}(:"do_something_\#{var}")
65-
RUBY
66-
end
47+
it 'does not register an offense when using string interpolation for `#{method}` method' do
48+
# NOTE: These methods don't support `::` when passing a symbol. const_get('A::B') is valid
49+
# but const_get(:'A::B') isn't. Since interpolated arguments may contain any content these
50+
# cases are not detected as an offense to prevent false positives.
51+
expect_no_offenses(<<~RUBY)
52+
#{method}("\#{module_name}class_name")
53+
RUBY
54+
end
55+
56+
it 'does not register an offense when using interpolated string argument' do
57+
expect_no_offenses(<<~RUBY)
58+
#{method}("do_something_\#{var}")
59+
RUBY
6760
end
6861
end
6962
end

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy