Class: RuboCop::Cop::Style::NumericPredicate

Inherits:
Base
  • Object
show all
Extended by:
AutoCorrector
Includes:
AllowedMethods, AllowedPattern, ConfigurableEnforcedStyle
Defined in:
lib/rubocop/cop/style/numeric_predicate.rb

Overview

Checks for usage of comparison operators (‘==`, `>`, `<`) to test numbers as zero, positive, or negative. These can be replaced by their respective predicate methods. This cop can also be configured to do the reverse.

This cop’s allowed methods can be customized with ‘AllowedMethods`. By default, there are no allowed methods.

This cop disregards ‘#nonzero?` as its value is truthy or falsey, but not `true` and `false`, and thus not always interchangeable with `!= 0`.

This cop allows comparisons to global variables, since they are often populated with objects which can be compared with integers, but are not themselves ‘Integer` polymorphic.

Examples:

EnforcedStyle: predicate (default)

# bad
foo == 0
0 > foo
bar.baz > 0

# good
foo.zero?
foo.negative?
bar.baz.positive?

EnforcedStyle: comparison

# bad
foo.zero?
foo.negative?
bar.baz.positive?

# good
foo == 0
0 > foo
bar.baz > 0

AllowedMethods: [] (default) with EnforcedStyle: predicate

# bad
foo == 0
0 > foo
bar.baz > 0

AllowedMethods: [==] with EnforcedStyle: predicate

# good
foo == 0

# bad
0 > foo
bar.baz > 0

AllowedPatterns: [] (default) with EnforcedStyle: comparison

# bad
foo.zero?
foo.negative?
bar.baz.positive?

AllowedPatterns: [‘zero’] with EnforcedStyle: predicate

# good
# bad
foo.zero?

# bad
foo.negative?
bar.baz.positive?

Constant Summary collapse

MSG =
'Use `%<prefer>s` instead of `%<current>s`.'
REPLACEMENTS =
{ 'zero?' => '==', 'positive?' => '>', 'negative?' => '<' }.freeze
RESTRICT_ON_SEND =
%i[== > < positive? negative? zero?].freeze

Instance Attribute Summary

Attributes inherited from Base

#config, #processed_source

Instance Method Summary collapse

Methods included from AutoCorrector

support_autocorrect?

Methods included from ConfigurableEnforcedStyle

#alternative_style, #alternative_styles, #ambiguous_style_detected, #correct_style_detected, #detected_style, #detected_style=, #no_acceptable_style!, #no_acceptable_style?, #opposite_style_detected, #style, #style_configured?, #style_detected, #style_parameter_name, #supported_styles, #unexpected_style_detected

Methods inherited from Base

#active_support_extensions_enabled?, #add_global_offense, #add_offense, #always_autocorrect?, autocorrect_incompatible_with, badge, #begin_investigation, #callbacks_needed, callbacks_needed, #config_to_allow_offenses, #config_to_allow_offenses=, #contextual_autocorrect?, #cop_config, cop_name, #cop_name, department, documentation_url, exclude_from_registry, #excluded_file?, #external_dependency_checksum, inherited, #initialize, #inspect, joining_forces, lint?, match?, #message, #offenses, #on_investigation_end, #on_new_investigation, #on_other_file, #parse, #parser_engine, #ready, #relevant_file?, requires_gem, #string_literals_frozen_by_default?, support_autocorrect?, support_multiple_source?, #target_rails_version, #target_ruby_version

Methods included from ExcludeLimit

#exclude_limit

Methods included from AutocorrectLogic

#autocorrect?, #autocorrect_enabled?, #autocorrect_requested?, #autocorrect_with_disable_uncorrectable?, #correctable?, #disable_uncorrectable?, #safe_autocorrect?

Methods included from IgnoredNode

#ignore_node, #ignored_node?, #part_of_ignored_node?

Methods included from Util

silence_warnings

Constructor Details

This class inherits a constructor from RuboCop::Cop::Base

Instance Method Details

#on_send(node) ⇒ Object



90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/rubocop/cop/style/numeric_predicate.rb', line 90

def on_send(node)
  numeric, replacement = check(node)
  return unless numeric

  return if allowed_method_name?(node.method_name) ||
            node.each_ancestor(:send, :block).any? do |ancestor|
              allowed_method_name?(ancestor.method_name)
            end

  message = format(MSG, prefer: replacement, current: node.source)
  add_offense(node, message: message) do |corrector|
    corrector.replace(node, replacement)
  end
end