Skip to content
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

Performance/ReverseEach fix is not equivalent #36

Closed
cyclotron3k opened this issue Sep 28, 2018 · 2 comments · Fixed by #221
Closed

Performance/ReverseEach fix is not equivalent #36

cyclotron3k opened this issue Sep 28, 2018 · 2 comments · Fixed by #221

Comments

@cyclotron3k
Copy link

The ReverseEach performance cop suggests replacing .reverse.each with .reverse_each.

Unfortunately reverse_each is not a drop-in replacement for reverse.each as there is a subtle difference between the two:

payments = [200, 400, 800, 100]
max_payment = payments.sort.reverse.each { |x| "do something" }.last
# => 100
max_payment = payments.sort.reverse_each { |x| "do something" }.last
# => 800

In other words, reverse_each runs the block over each element in reverse order, as expected, but then it returns the un-reversed enumerable.

Solution

It's a valid performance improvement in most scenarios, but it needs to come with a big warning. I also think that auto-correction should be disabled for this cop because it can break code.

RuboCop version

rubocop -V
0.59.2 (using Parser 2.5.1.2, running on ruby 2.5.1 x86_64-linux)
@rrosenblum
Copy link
Contributor

rrosenblum commented Sep 28, 2018

The example that you provided is a bit of an edge case that we can account for in the cop. I find it a bit unusual to chain a method onto each since each returns the original object rather than something that has been modified. I can also see where someone would do this to simplify the code.

We should also check to make sure that reverse.each isn't being used as the return value of a method or being assigned to a variable. Both of those scenarios could produce the same issue.

@koic koic transferred this issue from rubocop/rubocop Mar 14, 2019
@luke-hill
Copy link

This may not be desireable. But if there is a noticeable performance upgrade, could you not just tack #reverse onto the end of the original run? So you get reverse_each {}.reverse

koic added a commit to koic/rubocop-performance that referenced this issue Mar 4, 2021
Fixes rubocop#36.

This PR fixes a false positive for `Performance/ReverseEach`
when `each` is called on `reverse` and using the result value.
@koic koic closed this as completed in #221 Mar 6, 2021
koic added a commit that referenced this issue Mar 6, 2021
…reverse_each

[Fix #36] Fix a false positive for `Performance/ReverseEach`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants