From 173ff465f49ff4bb5bdfa726e413b773f79a79f9 Mon Sep 17 00:00:00 2001 From: Lovro Bikic Date: Sat, 14 Jun 2025 16:34:48 +0200 Subject: [PATCH] Add collection querying rule --- README.adoc | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/README.adoc b/README.adoc index 17316c47..1e8f9e74 100644 --- a/README.adoc +++ b/README.adoc @@ -4690,6 +4690,54 @@ ary[..42] ary[0..42] ---- +=== Collection querying [[collection-querying]] + +When possible, use https://docs.ruby-lang.org/en/master/Enumerable.html#module-Enumerable-label-Methods+for+Querying[predicate methods from `Enumerable`] rather than expressions with `#count`, `#length` or `#size`. + +Querying methods express the intention more clearly and are more performant in some cases. For example, `articles.any?(&:published?)` is more readable than `articles.count(&:published?) > 0` and also more performant because `#any?` stops execution as soon as the first published article is found, while `#count` traverses the whole collection. + +[source,ruby] +---- +# bad +array.count > 0 +array.length > 0 +array.size > 0 + +array.count(&:something).positive? + +array.count(&:something) == 0 + +array.count(&:something) == 1 + +# good +array.any? + +array.any?(&:something) + +array.none?(&:something) + +array.one?(&:something) +---- + +[NOTE] +-- +Predicate methods without arguments can't replace `count` expressions when collection includes falsey values: +[source,ruby] +---- +[nil, false].any? +# => false + +[nil, false].none? +# => true + +[nil].one? +# => false + +[false].one? +# => false +---- +-- + == Numbers === Underscores in Numerics [[underscores-in-numerics]]