class RuboCop::Cop::Style::YodaCondition
Enforces or forbids Yoda conditions, i.e. comparison operations where the order of expression is reversed. eg. ‘5 == x`
@safety
This cop is unsafe because comparison operators can be defined differently on different classes, and are not guaranteed to have the same result if reversed. For example: [source,ruby] ---- class MyKlass def ==(other) true end end obj = MyKlass.new obj == 'string' #=> true 'string' == obj #=> false ----
@example EnforcedStyle: forbid_for_all_comparison_operators (default)
# bad 99 == foo "bar" != foo 42 >= foo 10 < bar 99 == CONST # good foo == 99 foo == "bar" foo <= 42 bar > 10 CONST == 99 "#{interpolation}" == foo /#{interpolation}/ == foo
@example EnforcedStyle: forbid_for_equality_operators_only
# bad 99 == foo "bar" != foo # good 99 >= foo 3 < a && a < 5
@example EnforcedStyle: require_for_all_comparison_operators
# bad foo == 99 foo == "bar" foo <= 42 bar > 10 # good 99 == foo "bar" != foo 42 >= foo 10 < bar
@example EnforcedStyle: require_for_equality_operators_only
# bad 99 >= foo 3 < a && a < 5 # good 99 == foo "bar" != foo
Constants
- EQUALITY_OPERATORS
- MSG
- NONCOMMUTATIVE_OPERATORS
- PROGRAM_NAMES
- RESTRICT_ON_SEND
- REVERSE_COMPARISON
Public Instance Methods
on_send(node)
click to toggle source
# File lib/rubocop/cop/style/yoda_condition.rb, line 94 def on_send(node) return unless yoda_compatible_condition?(node) return if (equality_only? && non_equality_operator?(node)) || file_constant_equal_program_name?(node) || valid_yoda?(node) add_offense(node) do |corrector| corrector.replace(actual_code_range(node), corrected_code(node)) end end
Private Instance Methods
actual_code_range(node)
click to toggle source
# File lib/rubocop/cop/style/yoda_condition.rb, line 149 def actual_code_range(node) range_between(node.source_range.begin_pos, node.source_range.end_pos) end
constant_portion?(node)
click to toggle source
# File lib/rubocop/cop/style/yoda_condition.rb, line 145 def constant_portion?(node) node.literal? || node.const_type? end
corrected_code(node)
click to toggle source
# File lib/rubocop/cop/style/yoda_condition.rb, line 138 def corrected_code(node) lhs = node.receiver rhs = node.first_argument "#{rhs.source} #{reverse_comparison(node.method_name)} #{lhs.source}" end
enforce_yoda?()
click to toggle source
# File lib/rubocop/cop/style/yoda_condition.rb, line 107 def enforce_yoda? style == :require_for_all_comparison_operators || style == :require_for_equality_operators_only end
equality_only?()
click to toggle source
# File lib/rubocop/cop/style/yoda_condition.rb, line 112 def equality_only? style == :forbid_for_equality_operators_only || style == :require_for_equality_operators_only end
interpolation?(node)
click to toggle source
# File lib/rubocop/cop/style/yoda_condition.rb, line 173 def interpolation?(node) return true if node.dstr_type? node.regexp_type? && node.interpolation? end
message(node)
click to toggle source
rubocop:enable Metrics/CyclomaticComplexity
# File lib/rubocop/cop/style/yoda_condition.rb, line 134 def message(node) format(MSG, source: node.source) end
non_equality_operator?(node)
click to toggle source
# File lib/rubocop/cop/style/yoda_condition.rb, line 157 def non_equality_operator?(node) !EQUALITY_OPERATORS.include?(node.method_name) end
noncommutative_operator?(node)
click to toggle source
# File lib/rubocop/cop/style/yoda_condition.rb, line 161 def noncommutative_operator?(node) NONCOMMUTATIVE_OPERATORS.include?(node.method_name) end
program_name?(name)
click to toggle source
# File lib/rubocop/cop/style/yoda_condition.rb, line 169 def program_name?(name) PROGRAM_NAMES.include?(name) end
reverse_comparison(operator)
click to toggle source
# File lib/rubocop/cop/style/yoda_condition.rb, line 153 def reverse_comparison(operator) REVERSE_COMPARISON.fetch(operator.to_s, operator) end
source_file_path_constant?(node)
click to toggle source
# File lib/rubocop/cop/style/yoda_condition.rb, line 165 def source_file_path_constant?(node) node.source == '__FILE__' end
valid_yoda?(node)
click to toggle source
rubocop:disable Metrics/CyclomaticComplexity
# File lib/rubocop/cop/style/yoda_condition.rb, line 122 def valid_yoda?(node) return true unless (rhs = node.first_argument) lhs = node.receiver return true if (constant_portion?(lhs) && constant_portion?(rhs)) || (!constant_portion?(lhs) && !constant_portion?(rhs)) || interpolation?(lhs) enforce_yoda? ? constant_portion?(lhs) : constant_portion?(rhs) end
yoda_compatible_condition?(node)
click to toggle source
# File lib/rubocop/cop/style/yoda_condition.rb, line 117 def yoda_compatible_condition?(node) node.comparison_method? && !noncommutative_operator?(node) end