Class: RuboCop::Cop::DevDoc::Style::RepeatedSafeNavigationReceiver
- Inherits:
-
Base
- Object
- Base
- RuboCop::Cop::DevDoc::Style::RepeatedSafeNavigationReceiver
- Defined in:
- lib/rubocop/cop/dev_doc/style/repeated_safe_navigation_receiver.rb
Overview
Avoid using ‘&.` on the same receiver more than once in a method body.
## Rationale When a receiver appears with ‘&.` repeatedly across a method, the reader has to mentally re-evaluate the nil case at every call, and the intent of each `&.` becomes ambiguous — is this call nullable for a fresh reason, or is the dev just mirroring the earlier `&.` out of habit? Repetition also propagates nil silently into downstream comparisons (`current_user&.id == something` evaluates to `nil == something`, which is false but not for the reason the reader expects).
Resolve the nil case once at the top of the method, then use the local with plain ‘.`:
❌
def show?
current_user&.super_admin? ||
current_user&.developer? ||
current_user&.admin_of_organization?(organization)
end
✔️ Guard once, then plain calls
def show?
return false unless current_user
current_user.super_admin? ||
current_user.developer? ||
current_user.admin_of_organization?(organization)
end
✔️ Alternative — assign-and-test in the condition
def label
if (user = current_user)
"#{user.full_name} <#{user.email}>"
end
end
The cop is policy-safe by design: it does not assume anything about ‘current_user` non-nullability or branching semantics — it only flags repeated `&.` on the same receiver, which is a smell regardless of whether the receiver is `current_user`, a model attribute, or a local variable.
## Exception Legitimate cases (e.g. when the repeated calls are conceptually distinct sources that happen to share source spelling) go through inline ‘# rubocop:disable` with a reason.
NOTE: Receivers are compared by source text — two ‘&.` calls share a receiver if their source spelling matches verbatim. The cop does not perform flow analysis, so a receiver reassigned between uses is not detected (false negative).
NOTE: Scope is the enclosing ‘def`/`defs` body. The cop does not partition by inner blocks, so the same parameter name reused across separate block bodies in one method may produce a false positive — inline-disable with a reason if it surfaces.
Constant Summary collapse
- MSG =
"Receiver `%<receiver>s` already used with `&.` earlier in this method — assign once and use `.` after.".freeze
Instance Method Summary collapse
- #on_def(node) ⇒ Object (also: #on_defs)
Instance Method Details
#on_def(node) ⇒ Object Also known as: on_defs
90 91 92 |
# File 'lib/rubocop/cop/dev_doc/style/repeated_safe_navigation_receiver.rb', line 90 def on_def(node) check_method(node) end |