Class: RuboCop::Cop::Performance::CaseWhenSplat

Inherits:
Base
  • Object
show all
Extended by:
AutoCorrector
Includes:
Alignment, CommentsHelp, RangeHelp
Defined in:
lib/rubocop/cop/performance/case_when_splat.rb

Overview

Reordering when conditions with a splat to the end of the when branches can improve performance.

Ruby has to allocate memory for the splat expansion every time that the case when statement is run. Since Ruby does not support fall through inside of case when, like some other languages do, the order of the when branches should not matter. By placing any splat expansions at the end of the list of when branches we will reduce the number of times that memory has to be allocated for the expansion. The exception to this is if multiple of your when conditions can be true for any given condition. A likely scenario for this defining a higher level when condition to override a condition that is inside of the splat expansion.

Examples:

# bad
case foo
when *condition
  bar
when baz
  foobar
end

case foo
when *[1, 2, 3, 4]
  bar
when 5
  baz
end

# good
case foo
when baz
  foobar
when *condition
  bar
end

case foo
when 1, 2, 3, 4
  bar
when 5
  baz
end

Constant Summary collapse

MSG =
'Reordering `when` conditions with a splat to the end of the `when` branches can improve performance.'
ARRAY_MSG =
'Pass the contents of array literals directly to `when` conditions.'

Instance Method Summary collapse

Instance Method Details

#on_case(case_node) ⇒ Object



67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/rubocop/cop/performance/case_when_splat.rb', line 67

def on_case(case_node)
  when_conditions = case_node.when_branches.flat_map(&:conditions)

  splat_offenses(when_conditions).reverse_each do |condition|
    next if ignored_node?(condition.parent)

    ignore_node(condition.parent)
    variable, = *condition
    message = variable.array_type? ? ARRAY_MSG : MSG
    add_offense(range(condition), message: message) do |corrector|
      autocorrect(corrector, condition.parent)
    end
  end
end