class RuboCop::Cop::Style::TrailingUnderscoreVariable
Checks for extra underscores in variable assignment.
@example
# bad a, b, _ = foo() a, b, _, = foo() a, _, _ = foo() a, _, _, = foo() # good a, b, = foo() a, = foo() *a, b, _ = foo() # => We need to know to not include 2 variables in a a, *b, _ = foo() # => The correction `a, *b, = foo()` is a syntax error
@example AllowNamedUnderscoreVariables: true (default)
# good a, b, _something = foo()
@example AllowNamedUnderscoreVariables: false
# bad a, b, _something = foo()
Constants
- DISALLOW
- MSG
- UNDERSCORE
Public Instance Methods
on_masgn(node)
click to toggle source
# File lib/rubocop/cop/style/trailing_underscore_variable.rb, line 41 def on_masgn(node) ranges = unneeded_ranges(node) ranges.each do |range| good_code = node.source offset = range.begin_pos - node.source_range.begin_pos good_code[offset, range.size] = '' add_offense(range, message: format(MSG, code: good_code)) do |corrector| corrector.remove(range) end end end
Private Instance Methods
allow_named_underscore_variables()
click to toggle source
# File lib/rubocop/cop/style/trailing_underscore_variable.rb, line 92 def allow_named_underscore_variables @allow_named_underscore_variables ||= cop_config['AllowNamedUnderscoreVariables'] end
children_offenses(variables)
click to toggle source
# File lib/rubocop/cop/style/trailing_underscore_variable.rb, line 125 def children_offenses(variables) variables.select(&:mlhs_type?).flat_map { |v| unneeded_ranges(v) } end
find_first_offense(variables)
click to toggle source
# File lib/rubocop/cop/style/trailing_underscore_variable.rb, line 57 def find_first_offense(variables) first_offense = find_first_possible_offense(variables.reverse) return unless first_offense return if splat_variable_before?(first_offense, variables) first_offense end
find_first_possible_offense(variables)
click to toggle source
# File lib/rubocop/cop/style/trailing_underscore_variable.rb, line 66 def find_first_possible_offense(variables) variables.reduce(nil) do |offense, variable| break offense unless DISALLOW.include?(variable.type) var, = *variable var, = *var break offense if (allow_named_underscore_variables && var != :_) || !var.to_s.start_with?(UNDERSCORE) variable end end
main_node_offense(node)
click to toggle source
# File lib/rubocop/cop/style/trailing_underscore_variable.rb, line 108 def main_node_offense(node) node.masgn_type? ? (mlhs_node, right = *node) : mlhs_node = node variables = *mlhs_node first_offense = find_first_offense(variables) return unless first_offense if unused_variables_only?(first_offense, variables) return unused_range(node.type, mlhs_node, right) end return range_for_parentheses(first_offense, mlhs_node) if Util.parentheses?(mlhs_node) range_between(first_offense.source_range.begin_pos, node.loc.operator.begin_pos) end
range_for_parentheses(offense, left)
click to toggle source
# File lib/rubocop/cop/style/trailing_underscore_variable.rb, line 146 def range_for_parentheses(offense, left) range_between(offense.source_range.begin_pos - 1, left.loc.expression.end_pos - 1) end
reverse_index(collection, item)
click to toggle source
# File lib/rubocop/cop/style/trailing_underscore_variable.rb, line 88 def reverse_index(collection, item) collection.size - 1 - collection.reverse.index(item) end
splat_variable_before?(first_offense, variables)
click to toggle source
# File lib/rubocop/cop/style/trailing_underscore_variable.rb, line 80 def splat_variable_before?(first_offense, variables) # Account for cases like `_, *rest, _`, where we would otherwise get # the index of the first underscore. first_offense_index = reverse_index(variables, first_offense) variables[0...first_offense_index].any?(&:splat_type?) end
unneeded_ranges(node)
click to toggle source
# File lib/rubocop/cop/style/trailing_underscore_variable.rb, line 96 def unneeded_ranges(node) node.masgn_type? ? (mlhs_node, = *node) : mlhs_node = node variables = *mlhs_node main_offense = main_node_offense(node) if main_offense.nil? children_offenses(variables) else children_offenses(variables) << main_offense end end
unused_range(node_type, mlhs_node, right)
click to toggle source
# File lib/rubocop/cop/style/trailing_underscore_variable.rb, line 133 def unused_range(node_type, mlhs_node, right) start_range = mlhs_node.source_range.begin_pos end_range = case node_type when :masgn right.source_range.begin_pos when :mlhs mlhs_node.source_range.end_pos end range_between(start_range, end_range) end
unused_variables_only?(offense, variables)
click to toggle source
# File lib/rubocop/cop/style/trailing_underscore_variable.rb, line 129 def unused_variables_only?(offense, variables) offense.source_range == variables.first.source_range end