Class: RuboCop::Cop::DevDoc::Style::MinimizeVariableScope
- Inherits:
-
Base
- Object
- Base
- RuboCop::Cop::DevDoc::Style::MinimizeVariableScope
- Defined in:
- lib/rubocop/cop/dev_doc/style/minimize_variable_scope.rb
Overview
Assign a variable inside the ‘if` condition that guards it, so the variable’s scope is the branch that actually uses it.
## Rationale When a local is assigned and then immediately gated by a truthiness check, hoisting the assignment to its own line widens its scope to the whole method and separates the binding from the guard. Folding the assignment into the condition (with parentheses) keeps the variable local to the branch that uses it and reads as one thought.
❌
token = params[:token]
if token
authenticate(token)
end
✔️
if (token = params[:token])
authenticate(token)
end
Parentheses around the assignment silence Ruby’s “assignment in condition” warning and signal the assignment is intentional.
## When it fires Only when the assigned variable is used only inside the guarding ‘if` — its condition plus the true branch — and is read at least once in that branch. If the variable is read in the `else` branch or after the block, folding wouldn’t narrow its scope, so the cop leaves it.
## Exception When the assigned expression is long, inlining it into the condition hurts readability more than the scope-narrowing helps. Keep the two-line form and inline-‘disable` with a reason.
NOTE: Conservative by design — it skips reassigned variables, ‘op_asgn` (`+=`, `||=`), compound/comparison conditions, and scopes containing a nested `def` or a block that rebinds the same name. Those are left un-flagged rather than risk a wrong rewrite.
Constant Summary collapse
- MSG =
"Assign `%<name>s` inside the `if` condition " \ "(`if (%<name>s = ...)`) so its scope is the branch that uses it.".freeze
- TRUTHY_PREDICATES =
Truthiness-shaped predicates we fold. Comparisons (‘x == 1`) are deliberately excluded — folding those reads as assignment-in-condition.
%i[present? any? presence].freeze
Instance Method Summary collapse
Instance Method Details
#on_lvasgn(node) ⇒ Object
64 65 66 67 68 69 70 71 72 73 74 |
# File 'lib/rubocop/cop/dev_doc/style/minimize_variable_scope.rb', line 64 def on_lvasgn(node) name, value = *node return unless value if_node = guarding_if(node) return unless if_node return unless truthiness_check?(if_node.condition, name) return unless confined_to_if?(node, if_node, name) add_offense(node.loc.name, message: format(MSG, name: name)) end |