Class: Overule::Condition

Inherits:
Object
  • Object
show all
Defined in:
lib/overule/condition.rb

Overview

Evaluates conditions defined in rules against a given context Conditions are used to determine whether actions should be executed based on the state of variables in the context

Constant Summary collapse

NUMERIC_DATATYPES =
%w[number integer float decimal].freeze
ORDERING_OPS =
%w[gt lt gte lte range].freeze

Class Method Summary collapse

Class Method Details

.coerce(actual, expected, datatype, op) ⇒ Object

Coerce numeric strings before ordering comparisons so that “1220000” > “2000000” doesn’t compare lexically.



23
24
25
26
27
28
# File 'lib/overule/condition.rb', line 23

def self.coerce(actual, expected, datatype, op)
  return [actual, expected] unless ORDERING_OPS.include?(op)
  return [actual, expected] unless NUMERIC_DATATYPES.include?(datatype)

  [to_number(actual), to_number(expected)]
end

.evaluate(conditions, context) ⇒ Object



9
10
11
12
13
14
15
16
17
18
19
# File 'lib/overule/condition.rb', line 9

def self.evaluate(conditions, context)
  return [] if conditions.empty?

  conditions.map do |condition|
    actual   = context.get(condition["var"])
    expected = condition["value"]
    actual, expected = coerce(actual, expected, condition["datatype"], condition["op"])

    Operator.operate(condition["op"], actual, expected)
  end
end

.to_number(value) ⇒ Object



30
31
32
33
34
35
36
37
38
# File 'lib/overule/condition.rb', line 30

def self.to_number(value)
  return value if value.is_a?(Numeric)
  return value.map { |v| to_number(v) } if value.is_a?(Array)
  return nil if value.nil?

  Float(value.to_s)
rescue ArgumentError, TypeError
  value
end