class RuboCop::Cop::Lint::Loop

Checks for uses of ‘begin…end while/until something`.

@safety

The cop is unsafe because behavior can change in some cases, including
if a local variable inside the loop body is accessed outside of it, or if the
loop body raises a `StopIteration` exception (which `Kernel#loop` rescues).

@example

# bad

# using while
begin
  do_something
end while some_condition

# good

# while replacement
loop do
  do_something
  break unless some_condition
end

# bad

# using until
begin
  do_something
end until some_condition

# good

# until replacement
loop do
  do_something
  break if some_condition
end

Constants

MSG

Public Instance Methods

on_until_post(node) click to toggle source
# File lib/rubocop/cop/lint/loop.rb, line 53
def on_until_post(node)
  register_offense(node)
end
on_while_post(node) click to toggle source
# File lib/rubocop/cop/lint/loop.rb, line 49
def on_while_post(node)
  register_offense(node)
end

Private Instance Methods

build_break_line(node) click to toggle source
# File lib/rubocop/cop/lint/loop.rb, line 73
def build_break_line(node)
  conditional_keyword = node.while_post_type? ? 'unless' : 'if'
  "break #{conditional_keyword} #{node.condition.source}\n#{indent(node)}"
end
keyword_and_condition_range(node) click to toggle source
# File lib/rubocop/cop/lint/loop.rb, line 69
def keyword_and_condition_range(node)
  node.body.loc.end.end.join(node.source_range.end)
end
register_offense(node) click to toggle source
# File lib/rubocop/cop/lint/loop.rb, line 59
def register_offense(node)
  body = node.body

  add_offense(node.loc.keyword) do |corrector|
    corrector.replace(body.loc.begin, 'loop do')
    corrector.remove(keyword_and_condition_range(node))
    corrector.insert_before(body.loc.end, build_break_line(node))
  end
end