123456789_123456789_123456789_123456789_123456789_

Class: RuboCop::Cop::Performance::ConstantRegexp

Relationships & Source Files
Super Chains via Extension / Inclusion / Inheritance
Class Chain:
self, AutoCorrector, Base
Instance Chain:
self, Base
Inherits: Base
  • Object
Defined in: lib/rubocop/cop/performance/constant_regexp.rb

Overview

Finds regular expressions with dynamic components that are all constants.

Ruby allocates a new Regexp object every time it executes a code containing such a regular expression. It is more efficient to extract it into a constant, memoize it, or add an /o option to perform #{} interpolation only once and reuse that Regexp object.

Examples:

# bad
def tokens(pattern)
  pattern.scan(TOKEN).reject { |token| token.match?(/\A#{SEPARATORS}\Z/) }
end

# good
ALL_SEPARATORS = /\A#{SEPARATORS}\Z/
def tokens(pattern)
  pattern.scan(TOKEN).reject { |token| token.match?(ALL_SEPARATORS) }
end

# good
def tokens(pattern)
  pattern.scan(TOKEN).reject { |token| token.match?(/\A#{SEPARATORS}\Z/o) }
end

# good
def separators
  @separators ||= /\A#{SEPARATORS}\Z/
end

Constant Summary

Class Method Summary

Instance Method Summary

Class Method Details

.autocorrect_incompatible_with

[ GitHub ]

  
# File 'lib/rubocop/cop/performance/constant_regexp.rb', line 41

def self.autocorrect_incompatible_with
  [RegexpMatch]
end

Instance Method Details

#include_interpolated_const?(node) ⇒ Boolean (private)

[ GitHub ]

  
# File 'lib/rubocop/cop/performance/constant_regexp.rb', line 64

def include_interpolated_const?(node)
  return false unless node.interpolation?

  node.each_child_node(:begin).all? do |begin_node|
    inner_node = begin_node.children.first
    inner_node && (inner_node.const_type? || regexp_escape?(inner_node))
  end
end

#on_regexp(node)

[ GitHub ]

  
# File 'lib/rubocop/cop/performance/constant_regexp.rb', line 45

def on_regexp(node)
  return if within_allowed_assignment?(node) || !include_interpolated_const?(node) || node.single_interpolation?

  add_offense(node) do |corrector|
    corrector.insert_after(node, 'o')
  end
end

#within_allowed_assignment?(node) ⇒ Boolean (private)

[ GitHub ]

  
# File 'lib/rubocop/cop/performance/constant_regexp.rb', line 55

def within_allowed_assignment?(node)
  node.each_ancestor(:casgn, :or_asgn).any?
end