class RuboCop::Cop::Style::RedundantSelf
Checks for redundant uses of `self`.
The usage of `self` is only needed when:
-
Sending a message to same object with zero arguments in presence of a method name clash with an argument or a local variable.
-
Calling an attribute writer to prevent a local variable assignment.
Note, with using explicit self you can only send messages with public or protected scope, you cannot send private messages this way.
Note we allow uses of `self` with operators because it would be awkward otherwise.
@example
# bad def foo(bar) self.baz end # good def foo(bar) self.bar # Resolves name clash with the argument. end def foo bar = 1 self.bar # Resolves name clash with the local variable. end def foo %w[x y z].select do |bar| self.bar == bar # Resolves name clash with argument of the block. end end
Constants
- KERNEL_METHODS
- KEYWORDS
- MSG
Public Class Methods
autocorrect_incompatible_with()
click to toggle source
# File lib/rubocop/cop/style/redundant_self.rb, line 55 def self.autocorrect_incompatible_with [ColonMethodCall, Layout::DotPosition] end
new(config = nil, options = nil)
click to toggle source
Calls superclass method
RuboCop::Cop::Base::new
# File lib/rubocop/cop/style/redundant_self.rb, line 59 def initialize(config = nil, options = nil) super @allowed_send_nodes = [] @local_variables_scopes = Hash.new { |hash, key| hash[key] = [] }.compare_by_identity end
Public Instance Methods
on_args(node)
click to toggle source
# File lib/rubocop/cop/style/redundant_self.rb, line 85 def on_args(node) node.children.each { |arg| on_argument(arg) } end
on_block(node)
click to toggle source
# File lib/rubocop/cop/style/redundant_self.rb, line 119 def on_block(node) add_scope(node, @local_variables_scopes[node]) end
Also aliased as: on_numblock
on_blockarg(node)
click to toggle source
# File lib/rubocop/cop/style/redundant_self.rb, line 89 def on_blockarg(node) on_argument(node) end
on_def(node)
click to toggle source
Using self.x to distinguish from local variable x
# File lib/rubocop/cop/style/redundant_self.rb, line 80 def on_def(node) add_scope(node) end
Also aliased as: on_defs
on_if(node)
click to toggle source
# File lib/rubocop/cop/style/redundant_self.rb, line 125 def on_if(node) # Allow conditional nodes to use `self` in the condition if that variable # name is used in an `lvasgn` or `masgn` within the `if`. node.child_nodes.each do |child_node| lhs, _rhs = *child_node if child_node.lvasgn_type? add_lhs_to_local_variables_scopes(node.condition, lhs) elsif child_node.masgn_type? add_masgn_lhs_variables(node.condition, lhs) end end end
on_in_pattern(node)
click to toggle source
# File lib/rubocop/cop/style/redundant_self.rb, line 103 def on_in_pattern(node) add_match_var_scopes(node) end
on_lvasgn(node)
click to toggle source
# File lib/rubocop/cop/style/redundant_self.rb, line 98 def on_lvasgn(node) lhs, rhs = *node add_lhs_to_local_variables_scopes(rhs, lhs) end
on_masgn(node)
click to toggle source
# File lib/rubocop/cop/style/redundant_self.rb, line 93 def on_masgn(node) lhs, rhs = *node add_masgn_lhs_variables(rhs, lhs) end
on_op_asgn(node)
click to toggle source
# File lib/rubocop/cop/style/redundant_self.rb, line 73 def on_op_asgn(node) lhs, _op, _rhs = *node allow_self(lhs) end
on_or_asgn(node)
click to toggle source
Assignment of self.x
# File lib/rubocop/cop/style/redundant_self.rb, line 67 def on_or_asgn(node) lhs, _rhs = *node allow_self(lhs) end
Also aliased as: on_and_asgn
on_send(node)
click to toggle source
# File lib/rubocop/cop/style/redundant_self.rb, line 107 def on_send(node) return unless node.self_receiver? && regular_method_call?(node) return if node.parent&.mlhs_type? return if allowed_send_node?(node) add_offense(node.receiver) do |corrector| corrector.remove(node.receiver) corrector.remove(node.loc.dot) end end
Private Instance Methods
add_lhs_to_local_variables_scopes(rhs, lhs)
click to toggle source
# File lib/rubocop/cop/style/redundant_self.rb, line 181 def add_lhs_to_local_variables_scopes(rhs, lhs) if rhs&.send_type? && !rhs.arguments.empty? rhs.arguments.each { |argument| @local_variables_scopes[argument] << lhs } else @local_variables_scopes[rhs] << lhs end end
add_masgn_lhs_variables(rhs, lhs)
click to toggle source
# File lib/rubocop/cop/style/redundant_self.rb, line 189 def add_masgn_lhs_variables(rhs, lhs) lhs.children.each do |child| add_lhs_to_local_variables_scopes(rhs, child.to_a.first) end end
add_match_var_scopes(in_pattern_node)
click to toggle source
# File lib/rubocop/cop/style/redundant_self.rb, line 195 def add_match_var_scopes(in_pattern_node) in_pattern_node.each_descendant(:match_var) do |match_var_node| @local_variables_scopes[in_pattern_node] << match_var_node.children.first end end
add_scope(node, local_variables = [])
click to toggle source
# File lib/rubocop/cop/style/redundant_self.rb, line 143 def add_scope(node, local_variables = []) node.each_descendant do |child_node| @local_variables_scopes[child_node] = local_variables end end
allow_self(node)
click to toggle source
# File lib/rubocop/cop/style/redundant_self.rb, line 175 def allow_self(node) return unless node.send_type? && node.self_receiver? @allowed_send_nodes << node end
allowed_send_node?(node)
click to toggle source
# File lib/rubocop/cop/style/redundant_self.rb, line 149 def allowed_send_node?(node) @allowed_send_nodes.include?(node) || @local_variables_scopes[node].include?(node.method_name) || node.each_ancestor.any? do |ancestor| @local_variables_scopes[ancestor].include?(node.method_name) end || KERNEL_METHODS.include?(node.method_name) end
on_argument(node)
click to toggle source
# File lib/rubocop/cop/style/redundant_self.rb, line 166 def on_argument(node) if node.mlhs_type? on_args(node) else name, = *node @local_variables_scopes[node] << name end end
regular_method_call?(node)
click to toggle source
# File lib/rubocop/cop/style/redundant_self.rb, line 158 def regular_method_call?(node) !(node.operator_method? || KEYWORDS.include?(node.method_name) || node.camel_case_method? || node.setter_method? || node.implicit_call?) end