-
-
Notifications
You must be signed in to change notification settings - Fork 3.1k
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
Add new Lint/ObjectEqualityOverride
cop
#13287
base: master
Are you sure you want to change the base?
Add new Lint/ObjectEqualityOverride
cop
#13287
Conversation
b772624
to
2c5cf6a
Compare
Before diving into the implementation details, here is some feedback on the requirements:
|
I don’t have anything ruby-specific at hand, but it is widely accepted that the Although the original motivation for this cop was to prevent runtime errors related to object comparisons (see the original issue), I firmly believe that the absence of class checks can lead to difficult-to-diagnose bugs. I recall struggling with a ruby-i18n-related bug after upgrading from Ruby 3.0.0 to 3.0.1, which was ultimately caused by a missing class check (see https://stackoverflow.com/questions/77830896/hash-related-behavior-mismatch-between-ruby-mri-3-0-0-and-3-0-1/77841475#77841475 for details) |
Well, For example, I think linter that enforces overriding |
Thanks, I understand your point now. Unfortunately, ATM I don't see anything related in the specification. |
2c5cf6a
to
fe4a4c7
Compare
Lint/UnsafeEqualityMethodDefinition
copLint/ObjectEqualityOverride
cop
fe4a4c7
to
c0a1e24
Compare
Fixed the issues you mentioned ( |
I understand the proposal, but something like this needs an iron-clad rationale before we can merge it. (mostly because I don't think such code is particularly common in the wild) @rubocop/rubocop-core As usual, in such tricky situations your thoughts would be most appreciated! |
# Identifies `eql?` method definitions which do not | ||
# check for argument class which might lead to runtime errors. |
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's a number of places in the PR where wording like this pops up but I don't think it's clear. Something like this might be better:
Identifies
eql?
method definitions which do not check the argument's class is the same as, or a descendant of, the current class.
Since there are more "good" possibilities than are enumerated in @example
, we should be more comprehensive.
Additionally "might lead to runtime errors" isn't a strong rationale IMO. What sort of runtime errors, and how does checking the class improve that?
This will likely register a false positive for methods along the lines of ( def eql?(other)
super && self.title == other.title
end and similarly (where def eql?(other)
foo.eql?(other) && self.title == other.title
end or even any generic method call could do the equality check but not be visible: def classes_eql?(other)
other.class == self.class
end
def eql?(other)
classes_eql?(other) && self.title == other.title
end |
Another category of false positives: def eql?(other)
# where CLASS_NAME is the actual class constant
other.is_a?(CLASS_NAME) && self.title == other.title
end |
c0a1e24
to
e0fc52d
Compare
This PR adds new
Lint/UnsafeEqualityMethodDefinition
cop that checks foreql?
and==
methods without argument class check.NOTE: currently there are exactly 5 offenses (some of them belong to public classes AFAICS) in the rubocop's codebase itself:
I'm not sure what to do with them.
Fixes #12289.
Before submitting the PR make sure the following are checked:
[Fix #issue-number]
(if the related issue exists).master
(if not - rebase it).bundle exec rake default
. It executes all tests and runs RuboCop on its own code.{change_type}_{change_description}.md
if the new code introduces user-observable changes. See changelog entry format for details.