Class: RuboCop::Cop::Kaizo::PluralCollectionName

Inherits:
Base
  • Object
show all
Includes:
AllowedMethods
Defined in:
lib/rubocop/cop/kaizo/plural_collection_name.rb

Overview

Checks that a method returning a collection is named in the plural. A singular name on a method handing back an array (def user returning [first, second]) misdescribes what the caller gets; the plural does the documenting for free.

Ruby has no return types, so "returns an array" is a heuristic, and this cop deliberately errs toward silence. A method is only flagged when every value it can return is unambiguously an array: an array literal, or a call to a method that returns an Array whatever its receiver (ArrayMethods, e.g. map, to_a, sort). One branch returning nil is enough to leave the method alone. Methods like select and reject are absent by design -- on a Hash they hand back a Hash.

A name counts as plural when it ends in s or appears in IrregularPlurals. Predicate (?), writer (=), and operator methods are exempt, as is initialize, and AllowedMethods exempts names outright. There is no autocorrection: renaming a method is a design decision, and only its author knows the right plural.

Examples:

# bad
def user
  [first_match, second_match]
end

# good
def users
  [first_match, second_match]
end
# good - not confidently an array, so not flagged
def user
  return nil if missing?

  [first_match, second_match]
end

Constant Summary collapse

MSG =
"Name a method that returns a collection in the plural. " \
"`%<name>s` returns an array.".freeze
ARRAY_METHODS =

Methods whose result is an Array regardless of the receiver. Kept deliberately short: anything whose return type follows its receiver (select on a Hash) would turn this cop into a false-positive mill.

%i[
  map flat_map collect collect_concat to_a entries sort sort_by zip
].freeze

Instance Method Summary collapse

Instance Method Details

#on_def(node) ⇒ Object Also known as: on_defs



55
56
57
58
59
60
# File 'lib/rubocop/cop/kaizo/plural_collection_name.rb', line 55

def on_def(node)
  return if exempt?(node)
  return unless returns_array?(node.body)

  add_offense(node.loc.name, message: format(MSG, name: node.method_name))
end