Class: RuboCop::Cop::Performance::IoReadlines

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

Overview

Identifies places where inefficient ‘readlines` method can be replaced by `each_line` to avoid fully loading file content into memory.

Examples:


# bad
File.readlines('testfile').each { |l| puts l }
IO.readlines('testfile', chomp: true).each { |l| puts l }

conn.readlines(10).map { |l| l.size }
file.readlines.find { |l| l.start_with?('#') }
file.readlines.each { |l| puts l }

# good
File.open('testfile', 'r').each_line { |l| puts l }
IO.open('testfile').each_line(chomp: true) { |l| puts l }

conn.each_line(10).map { |l| l.size }
file.each_line.find { |l| l.start_with?('#') }
file.each_line { |l| puts l }

Constant Summary collapse

MSG =
'Use `%<good>s` instead of `%<bad>s`.'
RESTRICT_ON_SEND =
(Enumerable.instance_methods + [:each]).freeze

Instance Method Summary collapse

Instance Method Details

#on_send(node) ⇒ Object



42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/rubocop/cop/performance/io_readlines.rb', line 42

def on_send(node)
  return unless (captured_values = readlines_on_class?(node) || readlines_on_instance?(node))

  enumerable_call, readlines_call, receiver = *captured_values

  range = offense_range(enumerable_call, readlines_call)
  good_method = build_good_method(enumerable_call)
  bad_method = build_bad_method(enumerable_call)

  add_offense(range, message: format(MSG, good: good_method, bad: bad_method)) do |corrector|
    autocorrect(corrector, enumerable_call, readlines_call, receiver)
  end
end