Class: RuboCop::Cop::Obsession::NoBreakOrNext

Inherits:
Base
  • Object
show all
Defined in:
lib/rubocop/cop/obsession/no_break_or_next.rb

Overview

This cop checks for next (and sometimes break) in loops.

  • For big loops, next or break indicates that the loop body has

significant logic, which means it should be moved into its own method, and you can convert the next or break into return and the like.

  • For small loops, you can just use normal conditions instead of next.

break is allowed.

Note: Sometimes loops can also be rethought, like transforming a loop + break into a while.

Examples:

# bad
github_teams.each do |github_team|
  next if github_team['size'] == 0
  team = @company.teams.find_or_initialize_by(github_team['id'])

  team.update!(
    name: github_team['name'],
    description: github_team['description'],
    owner: @company,
  )
end

# good
github_teams.each do |github_team| { |github_team| upsert_team(github_team) }

def upsert_team(github_team)
  return if github_team['size'] == 0
  team = @company.teams.find_or_initialize_by(github_team['id'])

  team.update!(
    name: github_team['name'],
    description: github_team['description'],
    owner: @company,
  )
end

# bad
def highlight
  blog_posts.each do |blog_post|
    next if !blog_post.published?

    self.highlighted = true
  end
end

# good
def highlight
  blog_posts.each do |blog_post|
    if blog_post.published?
      self.highlighted = true
    end
  end
end

Constant Summary collapse

BIG_LOOP_MSG =
'Avoid `break`/`next` in big loop, decompose into private method or rethink loop.'
NO_NEXT_MSG =
'Avoid `next` in loop, use conditions or rethink loop.'
BIG_LOOP_MIN_LINES =
7

Instance Method Summary collapse

Instance Method Details

#on_block(node) ⇒ Object



75
76
77
78
79
80
81
82
83
# File 'lib/rubocop/cop/obsession/no_break_or_next.rb', line 75

def on_block(node)
  return if !contains_break_or_next?(node)

  if big_loop?(node)
    add_offense(node, message: BIG_LOOP_MSG)
  elsif contains_next?(node)
    add_offense(node, message: NO_NEXT_MSG)
  end
end