class RuboCop::Cop::Lint::DisjunctiveAssignmentInConstructor
Checks constructors for disjunctive assignments (`||=`) that should be plain assignments.
So far, this cop is only concerned with disjunctive assignment of instance variables.
In ruby, an instance variable is nil until a value is assigned, so the disjunction is unnecessary. A plain assignment has the same effect.
@safety
This cop is unsafe because it can register a false positive when a method is redefined in a subclass that calls super. For example: [source,ruby] ---- class Base def initialize @config ||= 'base' end end class Derived < Base def initialize @config = 'derived' super end end ---- Without the disjunctive assignment, `Derived` will be unable to override the value for `@config`.
@example
# bad def initialize @x ||= 1 end # good def initialize @x = 1 end
Constants
- MSG
Public Instance Methods
on_def(node)
click to toggle source
# File lib/rubocop/cop/lint/disjunctive_assignment_in_constructor.rb, line 53 def on_def(node) check(node) end
Private Instance Methods
check(node)
click to toggle source
@param [DefNode] node a constructor definition
# File lib/rubocop/cop/lint/disjunctive_assignment_in_constructor.rb, line 60 def check(node) return unless node.method?(:initialize) check_body(node.body) end
check_body(body)
click to toggle source
# File lib/rubocop/cop/lint/disjunctive_assignment_in_constructor.rb, line 66 def check_body(body) return if body.nil? case body.type when :begin check_body_lines(body.child_nodes) else check_body_lines([body]) end end
check_body_lines(lines)
click to toggle source
@param [Array] lines the logical lines of the constructor
# File lib/rubocop/cop/lint/disjunctive_assignment_in_constructor.rb, line 78 def check_body_lines(lines) lines.each do |line| case line.type when :or_asgn check_disjunctive_assignment(line) else # Once we encounter something other than a disjunctive # assignment, we cease our investigation, because we can't be # certain that any future disjunctive assignments are offensive. # You're off the case, detective! break end end end
check_disjunctive_assignment(node)
click to toggle source
Add an offense if the LHS of the given disjunctive assignment is an instance variable.
For now, we only care about assignments to instance variables.
@param [Node] node a disjunctive assignment
# File lib/rubocop/cop/lint/disjunctive_assignment_in_constructor.rb, line 99 def check_disjunctive_assignment(node) lhs = node.child_nodes.first return unless lhs.ivasgn_type? add_offense(node.loc.operator) do |corrector| corrector.replace(node.loc.operator, '=') end end