class RuboCop::Cop::Lint::UselessTimes
do_something(1)
do_something
# good
1.times { |i| do_something(i) }
1.times { do_something }
0.times { do_something }
-5.times { do_something }
# bad
@example
usually OK, but might change behavior.
This cop is unsafe as ‘times` returns its receiver, which is
@safety
(`1.times`).
(when the integer <= 0) or that will only ever yield once
Checks for uses of `Integer#times` that will never yield
def autocorrect(corrector, count, node, proc_name)
def autocorrect(corrector, count, node, proc_name) if never_process?(count, node) remove_node(corrector, node) elsif !proc_name.empty? autocorrect_block_pass(corrector, node, proc_name) else autocorrect_block(corrector, node) end end
def autocorrect_block(corrector, node)
def autocorrect_block(corrector, node) block_arg = block_arg(node) return if block_reassigns_arg?(node, block_arg) source = node.body.source source.gsub!(/\b#{block_arg}\b/, '0') if block_arg corrector.replace(node, fix_indentation(source, node.loc.column...node.body.loc.column)) end
def autocorrect_block_pass(corrector, node, proc_name)
def autocorrect_block_pass(corrector, node, proc_name) corrector.replace(node, proc_name) end
def fix_indentation(source, range)
def fix_indentation(source, range) # Cleanup indentation in a multiline block source_lines = source.split("\n") source_lines[1..].each do |line| next if line.empty? line[range] = '' end source_lines.join("\n") end
def never_process?(count, node)
def never_process?(count, node) count < 1 || (node.block_type? && node.body.nil?) end
def on_send(node)
def on_send(node) return unless (count, proc_name = times_call?(node)) return if count > 1 # Get the block node if applicable node = node.block_node if node.block_literal? add_offense(node, message: format(MSG, count: count)) do |corrector| next if !own_line?(node) || node.parent&.send_type? autocorrect(corrector, count, node, proc_name) end end
def own_line?(node)
def own_line?(node) # If there is anything else on the line other than whitespace, # don't try to autocorrect processed_source.buffer.source_line(node.loc.line)[0...node.loc.column] !~ /\S/ end
def remove_node(corrector, node)
def remove_node(corrector, node) corrector.remove(range_by_whole_lines(node.source_range, include_final_newline: true)) end