class RuboCop::Cop::Performance::ArraySemiInfiniteRangeSlice

This cop identifies places where slicing arrays with semi-infinite ranges can be replaced by `Array#take` and `Array#drop`. This cop was created due to a mistake in microbenchmark and hence is disabled by default. Refer github.com/rubocop/rubocop-performance/pull/175#issuecomment-731892717 This cop is also unsafe for string slices because strings do not have `#take` and `#drop` methods.

@example

# bad
array[..2]
array[...2]
array[2..]
array[2...]
array.slice(..2)

# good
array.take(3)
array.take(2)
array.drop(2)
array.drop(2)
array.take(3)

Constants

MSG
RESTRICT_ON_SEND
SLICE_METHODS

Public Instance Methods

on_send(node) click to toggle source
# File lib/rubocop/cop/performance/array_semi_infinite_range_slice.rb, line 50
def on_send(node)
  endless_range_slice?(node) do |receiver, method_name, range_node|
    prefer = range_node.begin ? :drop : :take
    message = format(MSG, prefer: prefer, current: method_name)

    add_offense(node, message: message) do |corrector|
      corrector.replace(node, correction(receiver, range_node))
    end
  end
end

Private Instance Methods

correction(receiver, range_node) click to toggle source
# File lib/rubocop/cop/performance/array_semi_infinite_range_slice.rb, line 63
def correction(receiver, range_node)
  method_call = if range_node.begin
                  "drop(#{range_node.begin.value})"
                elsif range_node.irange_type?
                  "take(#{range_node.end.value + 1})"
                else
                  "take(#{range_node.end.value})"
                end

  "#{receiver.source}.#{method_call}"
end