Class: Hone::Patterns::StringConcatInLoop
- Defined in:
- lib/hone/patterns/string_concat_in_loop.rb
Overview
Pattern: String concatenation (+=) inside a loop -> use << or array join
Each string += operation creates a new string object, copying all previous
content. In a loop, this leads to O(n^2) memory allocations and copies.
Using << mutates the string in place, avoiding allocations.
Example:
# Bad - O(n^2) allocations
items.each { |item| result += item.to_s }
# Good - O(n) with in-place mutation
items.each { |item| result << item.to_s }
# Good - collect and join once
result = items.map(&:to_s).join
Impact: Significant in tight loops, avoids O(n^2) string copying
Constant Summary collapse
- LOOP_METHODS =
i[each each_with_index each_with_object map collect times upto downto step loop].freeze
Instance Attribute Summary
Attributes inherited from Base
Instance Method Summary collapse
-
#initialize(file_path) ⇒ StringConcatInLoop
constructor
A new instance of StringConcatInLoop.
-
#visit_call_node(node) ⇒ Object
Handle block-based loops (.each, .times, .map, loop, etc.).
-
#visit_class_variable_operator_write_node(node) ⇒ Object
Detect class variable += (e.g., @@str += "x").
-
#visit_for_node(node) ⇒ Object
Track when we enter/exit for loops.
-
#visit_global_variable_operator_write_node(node) ⇒ Object
Detect global variable += (e.g., $str += "x").
-
#visit_instance_variable_operator_write_node(node) ⇒ Object
Detect instance variable += (e.g., @str += "x").
-
#visit_local_variable_operator_write_node(node) ⇒ Object
Detect local variable += (e.g., str += "x").
-
#visit_until_node(node) ⇒ Object
Track when we enter/exit until loops.
-
#visit_while_node(node) ⇒ Object
Track when we enter/exit while loops.
Methods inherited from Base
#add_finding, inherited, scan_file
Constructor Details
#initialize(file_path) ⇒ StringConcatInLoop
Returns a new instance of StringConcatInLoop.
29 30 31 32 |
# File 'lib/hone/patterns/string_concat_in_loop.rb', line 29 def initialize(file_path) super @in_loop = false end |
Instance Method Details
#visit_call_node(node) ⇒ Object
Handle block-based loops (.each, .times, .map, loop, etc.)
50 51 52 53 54 55 56 |
# File 'lib/hone/patterns/string_concat_in_loop.rb', line 50 def visit_call_node(node) if loop_method?(node) && node.block with_context(:@in_loop, true) { super } else super end end |
#visit_class_variable_operator_write_node(node) ⇒ Object
Detect class variable += (e.g., @@str += "x")
71 72 73 74 |
# File 'lib/hone/patterns/string_concat_in_loop.rb', line 71 def visit_class_variable_operator_write_node(node) check_string_concat(node) super end |
#visit_for_node(node) ⇒ Object
Track when we enter/exit for loops
45 46 47 |
# File 'lib/hone/patterns/string_concat_in_loop.rb', line 45 def visit_for_node(node) with_context(:@in_loop, true) { super } end |
#visit_global_variable_operator_write_node(node) ⇒ Object
Detect global variable += (e.g., $str += "x")
77 78 79 80 |
# File 'lib/hone/patterns/string_concat_in_loop.rb', line 77 def visit_global_variable_operator_write_node(node) check_string_concat(node) super end |
#visit_instance_variable_operator_write_node(node) ⇒ Object
Detect instance variable += (e.g., @str += "x")
65 66 67 68 |
# File 'lib/hone/patterns/string_concat_in_loop.rb', line 65 def visit_instance_variable_operator_write_node(node) check_string_concat(node) super end |
#visit_local_variable_operator_write_node(node) ⇒ Object
Detect local variable += (e.g., str += "x")
59 60 61 62 |
# File 'lib/hone/patterns/string_concat_in_loop.rb', line 59 def visit_local_variable_operator_write_node(node) check_string_concat(node) super end |
#visit_until_node(node) ⇒ Object
Track when we enter/exit until loops
40 41 42 |
# File 'lib/hone/patterns/string_concat_in_loop.rb', line 40 def visit_until_node(node) with_context(:@in_loop, true) { super } end |
#visit_while_node(node) ⇒ Object
Track when we enter/exit while loops
35 36 37 |
# File 'lib/hone/patterns/string_concat_in_loop.rb', line 35 def visit_while_node(node) with_context(:@in_loop, true) { super } end |