-
-
Notifications
You must be signed in to change notification settings - Fork 3.4k
Add collection querying rule #962
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
7a3e2f8
to
97d9d25
Compare
Those two methods are not mutually interchangeable in the general case, are they? How important is it to have this guideline to get the referenced cop merged? |
Good questions! I'll answer what I can from my side.
It depends on method signature. With a block, they're mutually interchangeable (e.g. With no arguments, they're mutually interchangeable as long as the collection doesn't include falsy values (this has been noted in the rule).
This can be discussed, but assuming users work with truthy-value collections, I believe the semantics are the same, but predicates express them more clearly. For example, in this Rails report, the cop commonly caught stuff like
I'm not sure what should this comment signify, but there's a fair number of unsafe cops that are linked to style guide rules. |
Fair enough. However, we can’t guide those who have falsey values in enumerbles if they’re not passing a block.
Interesting mention.
True that. But that’s AR-specific. There’s also performance to consider rubocop/rails-style-guide#232 (comment)
I would guess because cop can’t reliably detect the type, eg Array vs AR::Relation. What do you think of reducing the scope of the guideline to only tell about the block form of My primary concern here is that those guidelines aim to prevent programmers from making mistakes, while using |
The guidelines are not laws, but rather suggestions for the most common cases that people might encounter. While there are caveats to be kept in mind, I do think that in most cases using the querying methods is the way to go and most likely people don't use them just because they forget about them (or are not aware of them in the first place). |
README.adoc
Outdated
@@ -4690,6 +4690,31 @@ 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`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You might also want to add a bit of rationale here (e.g. readability and better performance in some cases)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added a paragraph that explains readability and performance benefits
[source,ruby] | ||
---- | ||
# bad | ||
array.count > 0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Btw, there's also length
to consider. ;-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I figured as much although probably this should be also mentioned in the cop's docs as well, and we can also provide "conservative/aggressive" modes there in case someone wants to do a broader search in their codebase (e.g. on a one off basis). Anyways, that's not relevant to the PR here.
One more thing - this should probably mention In general for me the use of |
97d9d25
to
6769f36
Compare
array.count(&:something) == 1 | ||
|
||
# good | ||
array.any? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we exclude this?
Would it be possible to write a separate guideline for this?
If we harvest real-world-ruby-apps repos, what usages of count
will there be?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do you think this should be separated?
For methods like count
you should also keep in mind that it's a different method in Enumerable
and ActiveRelation
and it will probably be hard for us to tell them apart with a simple search.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed, but if it’s not a list of repos of Rails apps like real-world-ruby-apps, chances are higher that it’s an Enumerable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using any? instead of count may work, but is a time bomb, which will blow up when falsey values start appearing in the data.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we just need a couple of examples illustrating the behavior with such values, perhaps in a sidebar/callout.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we harvest real-world-ruby-apps repos, what usages of
count
will there be?
@pirj I've attached a report for real-world-ruby-apps here: rubocop/rubocop#14288 (comment)
Adds a rule to complement RuboCop PR rubocop/rubocop#14288.
This rule suggests to use Enumerable querying methods rather than expressions with
#count
to check if collections meet some criteria.