class RuboCop::Cop::Style::YodaExpression
Forbids Yoda expressions, i.e. binary operations (using ‘*`, `+`, `&`, `|`, and `^` operators) where the order of expression is reversed, eg. `1 + x`. This cop complements `Style/YodaCondition` cop, which has a similar purpose.
This cop is disabled by default to respect user intentions such as:
- source,ruby
config.server_port = 9000 + ENV.to_i
@safety
This cop is unsafe because binary operators can be defined differently on different classes, and are not guaranteed to have the same result if reversed.
@example SupportedOperators: [‘*’, ‘+’, ‘&’, ‘|’, ‘^’] (default)
# bad 10 * y 1 + x 1 & z 1 | x 1 ^ x 1 + CONST # good y * 10 x + 1 z & 1 x | 1 x ^ 1 CONST + 1 60 * 24
Constants
- MSG
- RESTRICT_ON_SEND
Public Instance Methods
Source
# File lib/rubocop/cop/style/yoda_expression.rb, line 47 def on_new_investigation @offended_nodes = nil end
Source
# File lib/rubocop/cop/style/yoda_expression.rb, line 51 def on_send(node) return unless supported_operators.include?(node.method_name.to_s) return unless node.arguments? lhs = node.receiver rhs = node.first_argument return unless yoda_expression_constant?(lhs, rhs) return if offended_ancestor?(node) message = format(MSG, source: rhs.source) add_offense(node, message: message) do |corrector| corrector.swap(lhs, rhs) end offended_nodes.add(node) end
Private Instance Methods
Source
# File lib/rubocop/cop/style/yoda_expression.rb, line 74 def constant_portion?(node) node.type?(:numeric, :const) end
Source
# File lib/rubocop/cop/style/yoda_expression.rb, line 82 def offended_ancestor?(node) node.each_ancestor(:send).any? { |ancestor| @offended_nodes&.include?(ancestor) } end
Source
# File lib/rubocop/cop/style/yoda_expression.rb, line 86 def offended_nodes @offended_nodes ||= Set.new.compare_by_identity end
Source
# File lib/rubocop/cop/style/yoda_expression.rb, line 78 def supported_operators Array(cop_config['SupportedOperators']) end
Source
# File lib/rubocop/cop/style/yoda_expression.rb, line 70 def yoda_expression_constant?(lhs, rhs) constant_portion?(lhs) && !constant_portion?(rhs) end