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