<commit_before># frozen_string_literal: true

require "bigdecimal/util"

module ActiveModel
  module Validations
    class NumericalityValidator < EachValidator # :nodoc:
      CHECKS = { greater_than: :>, greater_than_or_equal_to: :>=,
                 equal_to: :==, less_than: :<, less_than_or_equal_to: :<=,
                 odd: :odd?, even: :even?, other_than: :!= }.freeze

      RESERVED_OPTIONS = CHECKS.keys + [:only_integer]

      INTEGER_REGEX = /\A[+-]?\d+\z/

      HEXADECIMAL_REGEX = /\A[+-]?0[xX]/

      def check_validity!
        keys = CHECKS.keys - [:odd, :even]
        options.slice(*keys).each do |option, value|
          unless value.is_a?(Numeric) || value.is_a?(Proc) || value.is_a?(Symbol)
            raise ArgumentError, ":#{option} must be a number, a symbol or a proc"
          end
        end
      end

      def validate_each(record, attr_name, value, precision: Float::DIG, scale: nil)
        unless is_number?(value, precision, scale)
          record.errors.add(attr_name, :not_a_number, **filtered_options(value))
          return
        end

        if allow_only_integer?(record) && !is_integer?(value)
          record.errors.add(attr_name, :not_an_integer, **filtered_options(value))
          return
        end

        value = parse_as_number(value, precision, scale)

        options.slice(*CHECKS.keys).each do |option, option_value|
          case option
          when :odd, :even
            unless value.to_i.send(CHECKS[option])
              record.errors.add(attr_name, option, **filtered_options(value))
            end
          else
            case option_value
            when Proc
              option_value = option_value.call(record)
            when Symbol
              option_value = record.send(option_value)
            end

            option_value = parse_as_number(option_value, precision, scale)

            unless value.send(CHECKS[option], option_value)
              record.errors.add(attr_name, option, **filtered_options(value).merge!(count: option_value))
            end
          end<commit_msg>Integer#odd? and even? are public methods<commit_after># frozen_string_literal: true

require "bigdecimal/util"

module ActiveModel
  module Validations
    class NumericalityValidator < EachValidator # :nodoc:
      CHECKS = { greater_than: :>, greater_than_or_equal_to: :>=,
                 equal_to: :==, less_than: :<, less_than_or_equal_to: :<=,
                 odd: :odd?, even: :even?, other_than: :!= }.freeze

      RESERVED_OPTIONS = CHECKS.keys + [:only_integer]

      INTEGER_REGEX = /\A[+-]?\d+\z/

      HEXADECIMAL_REGEX = /\A[+-]?0[xX]/

      def check_validity!
        keys = CHECKS.keys - [:odd, :even]
        options.slice(*keys).each do |option, value|
          unless value.is_a?(Numeric) || value.is_a?(Proc) || value.is_a?(Symbol)
            raise ArgumentError, ":#{option} must be a number, a symbol or a proc"
          end
        end
      end

      def validate_each(record, attr_name, value, precision: Float::DIG, scale: nil)
        unless is_number?(value, precision, scale)
          record.errors.add(attr_name, :not_a_number, **filtered_options(value))
          return
        end

        if allow_only_integer?(record) && !is_integer?(value)
          record.errors.add(attr_name, :not_an_integer, **filtered_options(value))
          return
        end

        value = parse_as_number(value, precision, scale)

        options.slice(*CHECKS.keys).each do |option, option_value|
          case option
          when :odd, :even
            unless value.to_i.public_send(CHECKS[option])
              record.errors.add(attr_name, option, **filtered_options(value))
            end
          else
            case option_value
            when Proc
              option_value = option_value.call(record)
            when Symbol
              option_value = record.send(option_value)
            end

            option_value = parse_as_number(option_value, precision, scale)

            unless value.send(CHECKS[option], option_value)
              record.errors.add(attr_name, option, **filtered_options(value).merge!(count: option_value))
            end
          end
{'fraction_non_alphanumeric': 0.11211616281837658, 'fraction_numerical': 0.00047607712449416806, 'mean_word_length': 2.313880126182965, 'pattern_counts': {'":': 2, '<': 9, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2888229', 'n_tokens_mistral': 1284, 'n_tokens_neox': 1257, 'n_words': 264}