Class: Dry::Logic::Rule

Inherits:
Object
  • Object
show all
Includes:
Core::Constants, Operators
Defined in:
lib/dry/logic/rule.rb

Direct Known Subclasses

Predicate

Defined Under Namespace

Classes: Predicate

Constant Summary collapse

DEFAULT_OPTIONS =
{ args: [].freeze }.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Operators

#and, #or, #then, #xor

Constructor Details

#initialize(predicate, options = DEFAULT_OPTIONS) ⇒ Rule

Returns a new instance of Rule.



31
32
33
34
35
36
# File 'lib/dry/logic/rule.rb', line 31

def initialize(predicate, options = DEFAULT_OPTIONS)
  @predicate = predicate
  @options = options
  @args = options[:args]
  @arity = options[:arity] || predicate.arity
end

Instance Attribute Details

#argsObject (readonly)

Returns the value of attribute args.



27
28
29
# File 'lib/dry/logic/rule.rb', line 27

def args
  @args
end

#arityObject (readonly)

Returns the value of attribute arity.



29
30
31
# File 'lib/dry/logic/rule.rb', line 29

def arity
  @arity
end

#optionsObject (readonly)

Returns the value of attribute options.



25
26
27
# File 'lib/dry/logic/rule.rb', line 25

def options
  @options
end

#predicateObject (readonly)

Returns the value of attribute predicate.



23
24
25
# File 'lib/dry/logic/rule.rb', line 23

def predicate
  @predicate
end

Instance Method Details

#[](*input) ⇒ Object



50
51
52
# File 'lib/dry/logic/rule.rb', line 50

def [](*input)
  arity == 0 ? predicate.() : predicate[*args, *input]
end

#ast(input = Undefined) ⇒ Object



87
88
89
# File 'lib/dry/logic/rule.rb', line 87

def ast(input = Undefined)
  [:predicate, [id, args_with_names(input)]]
end

#bind(object) ⇒ Object



64
65
66
67
68
69
70
71
72
73
# File 'lib/dry/logic/rule.rb', line 64

def bind(object)
  if UnboundMethod === predicate
    self.class.new(predicate.bind(object), options)
  else
    self.class.new(
      -> *args { object.instance_exec(*args, &predicate) },
      options.merge(arity: arity, parameters: parameters)
    )
  end
end

#call(*input) ⇒ Object



46
47
48
# File 'lib/dry/logic/rule.rb', line 46

def call(*input)
  Result.new(self[*input], id) { ast(*input) }
end

#curry(*new_args) ⇒ Object



54
55
56
57
58
59
60
61
62
# File 'lib/dry/logic/rule.rb', line 54

def curry(*new_args)
  all_args = args + new_args

  if all_args.size > arity
    raise ArgumentError, "wrong number of arguments (#{all_args.size} for #{arity})"
  else
    with(args: all_args)
  end
end

#eval_args(object) ⇒ Object



75
76
77
# File 'lib/dry/logic/rule.rb', line 75

def eval_args(object)
  with(args: args.map { |arg| UnboundMethod === arg ? arg.bind(object).() : arg })
end

#idObject



42
43
44
# File 'lib/dry/logic/rule.rb', line 42

def id
  options[:id]
end

#parametersObject



83
84
85
# File 'lib/dry/logic/rule.rb', line 83

def parameters
  options[:parameters] || predicate.parameters
end

#typeObject



38
39
40
# File 'lib/dry/logic/rule.rb', line 38

def type
  :rule
end

#with(new_opts) ⇒ Object



79
80
81
# File 'lib/dry/logic/rule.rb', line 79

def with(new_opts)
  self.class.new(predicate, options.merge(new_opts))
end