Rubocop: Ruby 2.6: CollectionMethods `filter` => `select`? `select` => `filter`?

Created on 25 Apr 2019  路  9Comments  路  Source: rubocop-hq/rubocop

Is your feature request related to a problem?

I just found out that ruby 2.6 (oh man I live in the past) introduced Enumerable#filter method.
https://ruby-doc.org/core-2.6.3/Enumerable.html#method-i-filter

Should this be added to CollectionMethods cop?
What should the preferred mapping be?

https://github.com/rubocop-hq/ruby-style-guide#map-find-select-reduce-size

Describe the solution you'd like

My vote would go for Enumerable#filter, to keep the parity with other programming languages (namely ES/JS), but it would be great to get more opinions on this.

stale

Most helpful comment

Yep, I agree that going forward we should prefer filter. I was actually one of the people who campaigned for the new alias to be added. We should update the style guide as well, but the wording there should be - select for older Rubies and filter for 2.6+.

All 9 comments

Yep, I agree that going forward we should prefer filter. I was actually one of the people who campaigned for the new alias to be added. We should update the style guide as well, but the wording there should be - select for older Rubies and filter for 2.6+.

Agreed!

We can use "target ruby version" to differentiate between < 2.6 and >= 2.6.
I'll have a look at how other cops did it and try to make a pull-request by the EOW.

I want to check if I'm on the right track.

I figured it would be way easier to simply create a new cop...until the support for ruby < 2.6 is dropped. (that will take a while)

Here's what I have so far (specs are c/p from collection_methods_spec.rb):
https://github.com/vfonic/rubocop/commit/107e78f4e5bb22ed5d37c5225d0ac0a174b6be0e

Is this a good approach or should I just add the code straight to CollectionMethods? (which would be harder to add and harder to read IMO)

EDIT: Nevermind everyhing below here. I figured it out. :D

Pay special attention to this line: https://github.com/vfonic/rubocop/commit/107e78f4e5bb22ed5d37c5225d0ac0a174b6be0e#diff-b57c58b340b10b6db789ff3c53659b3aR6

When I try to run the specs, I constantly get:

NameError:
uninitialized constant RuboCop::Cop::Style::CollectionMethodsFilter
Did you mean? RuboCop::Cop::Style::CollectionMethods

Where can I define this constant? How are all the other tests run?

I'm running the tests with: bundle exec rspec spec/rubocop/cop/style/collection_methods_filter_spec.rb

Any ideas why is this cop not being loaded?

Huh. That's interesting. I think #filter is much worse no matter how you look at it. 馃

The only prerequisite for #select and #reject to make intuitive sense is knowing some English. On the contrary, to intuitively grasp #filter, you need to know some other programming language. Why pander to other languages when Ruby already has a better option? 馃檪

Filter is a horribly bad name in those other languages as well, because it's the opposite of what it means in English. You don't filter things in. You filter things out, by selectively removing things. So intuitively filter should be equivalent to #reject, but in actuality it is #select.

Oh, well. Enough of my rambling. I was mostly surprised to see #filter make it in, but as long as it's configurable in RuboCop, everyone is free to use what they're more comfortable with. 馃檪

@Drenmi those are some great points!

You're right, #filter might sound like it's supposed to "filter out" some items.

I'm not a fan of #select because, although it sounds understandable in English, it doesn't always sound so clear in the context in which it is being used.
For example, it took me quite a while to finally remember/realize that #select is not an Active Record method, when querying the database. Also, #select could mean something similar to Active Record #pluck, where you only "select" certain attributes from the objects within the array (馃that's #map).

#find_all 馃 sounds the most appropriate then, if we use English language as the only context (and we decide to rule-out #select).

However, I'd still vote for #filter. First of all, #find_all "didn't make it" in the battle between #find_all and #select already. (I guess there has been some discussion on this before.)
Secondly, if we look at the other languages, JS, PHP(array_filter) and Python, they all use filter. I'd lean on what's more common in developers' world, rather than English.
For example, #map would be really confusing and hard to find someone who would tell you what it does from its name without knowing first. But it's (relatively) clear to all developers what it does.

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contribution and understanding!

This issues been automatically closed due to lack of activity. Feel free to re-open it if you ever come back to it.

@bbatsov
when can we expect changes in the style guide according to this discussion? Because we have already holy war in a project I working, about #select and #filters, and I agree in general about using #filter but I don't see changes about it in rubocop style guide, why you still didn't add them?

@anatols-baymaganov Just an oversight on my part. Please, open a ticket with the style guide and I'll update it when I can. Touching the RuboCop config is tricky, as it's a breaking change and can't happen before version 2.0.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ecbrodie picture ecbrodie  路  3Comments

bbatsov picture bbatsov  路  3Comments

bquorning picture bquorning  路  3Comments

millisami picture millisami  路  3Comments

deivid-rodriguez picture deivid-rodriguez  路  3Comments