class RuboCop::Cop::Style::ArrayFirstLast

Identifies usages of ‘arr` and `arr` and suggests to change them to use `arr.first` and `arr.last` instead.

The cop is disabled by default due to safety concerns.

@safety

This cop is unsafe because `[0]` or `[-1]` can be called on a Hash,
which returns a value for `0` or `-1` key, but changing these to use
`.first` or `.last` will return first/last tuple instead. Also, String
does not implement `first`/`last` methods.

@example

# bad
arr[0]
arr[-1]

# good
arr.first
arr.last
arr[0] = 2
arr[0][-2]

Constants

MSG
RESTRICT_ON_SEND

Public Instance Methods

on_send(node) click to toggle source

rubocop:disable Metrics/AbcSize

# File lib/rubocop/cop/style/array_first_last.rb, line 35
def on_send(node)
  return unless node.arguments.size == 1 && node.first_argument.int_type?

  value = node.first_argument.value
  return unless [0, -1].include?(value)

  node = innermost_braces_node(node)
  return if node.parent && brace_method?(node.parent)

  preferred = (value.zero? ? 'first' : 'last')
  add_offense(node.loc.selector, message: format(MSG, preferred: preferred)) do |corrector|
    corrector.replace(node.loc.selector, ".#{preferred}")
  end
end

Private Instance Methods

brace_method?(node) click to toggle source
# File lib/rubocop/cop/style/array_first_last.rb, line 58
def brace_method?(node)
  node.send_type? && (node.method?(:[]) || node.method?(:[]=))
end
innermost_braces_node(node) click to toggle source

rubocop:enable Metrics/AbcSize

# File lib/rubocop/cop/style/array_first_last.rb, line 53
def innermost_braces_node(node)
  node = node.receiver while node.receiver.send_type? && node.receiver.method?(:[])
  node
end