class Dry::Logic::Rule
def [](*input)
def [](*input) arity == 0 ? predicate.() : predicate[*args, *input] end
def args_with_names(*input)
def args_with_names(*input) parameters.map(&:last).zip(args + input) end
def ast(input = Undefined)
def ast(input = Undefined) [:predicate, [id, args_with_names(input)]] end
def bind(object)
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
def call(*input)
def call(*input) Result.new(self[*input], id) { ast(*input) } end
def curry(*new_args)
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
def eval_args(object)
def eval_args(object) with(args: args.map { |arg| UnboundMethod === arg ? arg.bind(object).() : arg }) end
def id
def id options[:id] end
def initialize(predicate, options = DEFAULT_OPTIONS)
def initialize(predicate, options = DEFAULT_OPTIONS) @predicate = predicate @options = options @args = options[:args] @arity = options[:arity] || predicate.arity end
def parameters
def parameters options[:parameters] || predicate.parameters end
def type
def type :rule end
def with(new_opts)
def with(new_opts) self.class.new(predicate, options.merge(new_opts)) end