Class: XlsFunction::Evaluators::FunctionEvaluator

Inherits:
Object
  • Object
show all
Includes:
ArgumentsDefinable, ClassDictionary, ErrorDetector, Evaluable
Defined in:
lib/xls_function/evaluators/function_evaluator.rb

Direct Known Subclasses

BinaryOperationEvaluator, XlsFunction::Evaluators::Functions::Abs, XlsFunction::Evaluators::Functions::And, XlsFunction::Evaluators::Functions::Asc, XlsFunction::Evaluators::Functions::Char, XlsFunction::Evaluators::Functions::Clean, XlsFunction::Evaluators::Functions::Code, XlsFunction::Evaluators::Functions::Concat, XlsFunction::Evaluators::Functions::DateFn, XlsFunction::Evaluators::Functions::Datevalue, XlsFunction::Evaluators::Functions::Day, XlsFunction::Evaluators::Functions::Dbcs, XlsFunction::Evaluators::Functions::EDate, XlsFunction::Evaluators::Functions::EOMonth, XlsFunction::Evaluators::Functions::Exact, XlsFunction::Evaluators::Functions::Find, XlsFunction::Evaluators::Functions::Fixed, XlsFunction::Evaluators::Functions::Hour, XlsFunction::Evaluators::Functions::If, XlsFunction::Evaluators::Functions::Ifs, XlsFunction::Evaluators::Functions::Int, XlsFunction::Evaluators::Functions::Iserror, XlsFunction::Evaluators::Functions::Isnumber, XlsFunction::Evaluators::Functions::Lambda, XlsFunction::Evaluators::Functions::Lambda::Function, XlsFunction::Evaluators::Functions::Left, XlsFunction::Evaluators::Functions::Len, XlsFunction::Evaluators::Functions::Let, XlsFunction::Evaluators::Functions::Lower, XlsFunction::Evaluators::Functions::Mid, XlsFunction::Evaluators::Functions::Minute, XlsFunction::Evaluators::Functions::Month, XlsFunction::Evaluators::Functions::Not, XlsFunction::Evaluators::Functions::Now, XlsFunction::Evaluators::Functions::Or, XlsFunction::Evaluators::Functions::POWER, XlsFunction::Evaluators::Functions::Proper, XlsFunction::Evaluators::Functions::Replace, XlsFunction::Evaluators::Functions::Rept, XlsFunction::Evaluators::Functions::Right, XlsFunction::Evaluators::Functions::Round, XlsFunction::Evaluators::Functions::RoundDown, XlsFunction::Evaluators::Functions::RoundUp, XlsFunction::Evaluators::Functions::Second, XlsFunction::Evaluators::Functions::Sign, XlsFunction::Evaluators::Functions::Sqrt, XlsFunction::Evaluators::Functions::Substitute, XlsFunction::Evaluators::Functions::Switch, XlsFunction::Evaluators::Functions::Text, XlsFunction::Evaluators::Functions::TimeFn, XlsFunction::Evaluators::Functions::Timevalue, XlsFunction::Evaluators::Functions::Today, XlsFunction::Evaluators::Functions::Trim, XlsFunction::Evaluators::Functions::Trunc, XlsFunction::Evaluators::Functions::Unichar, XlsFunction::Evaluators::Functions::Unicode, XlsFunction::Evaluators::Functions::Upper, XlsFunction::Evaluators::Functions::Value, XlsFunction::Evaluators::Functions::Year, UserDefinedFunctionFactory::ProcFunction

Class Method Summary collapse

Instance Method Summary collapse

Methods included from ClassDictionary

included

Methods included from ErrorDetector

#class_info, #class_name, included, #rescue_with

Methods included from ArgumentsDefinable

included

Methods included from Evaluable

included

Constructor Details

#initialize(context) ⇒ FunctionEvaluator

Returns a new instance of FunctionEvaluator.



12
13
14
# File 'lib/xls_function/evaluators/function_evaluator.rb', line 12

def initialize(context)
  @context = context
end

Class Method Details

.create(context) ⇒ Object



105
106
107
# File 'lib/xls_function/evaluators/function_evaluator.rb', line 105

def create(context)
  new(context)
end

.to_hObject



109
110
111
112
113
114
115
# File 'lib/xls_function/evaluators/function_evaluator.rb', line 109

def to_h
  {
    class: name,
    proc: to_proc,
    description: translated_description
  }
end

.to_proc(context = {}) ⇒ Object



121
122
123
124
125
# File 'lib/xls_function/evaluators/function_evaluator.rb', line 121

def to_proc(context = {})
  proc do |*arglist|
    new(arglist, context).evaluate
  end
end

.translated_descriptionObject



117
118
119
# File 'lib/xls_function/evaluators/function_evaluator.rb', line 117

def translated_description
  I18n.t("xls_function.descriptions.#{@register_key}", default: @description)
end

Instance Method Details

#arg_listObject



16
17
18
# File 'lib/xls_function/evaluators/function_evaluator.rb', line 16

def arg_list
  @arg_list ||= Array(context[:arglist])
end

#before_evalObject



33
34
35
# File 'lib/xls_function/evaluators/function_evaluator.rb', line 33

def before_eval
  eval_arglist
end

#convert_to(value, type) ⇒ Object



54
55
56
57
58
59
# File 'lib/xls_function/evaluators/function_evaluator.rb', line 54

def convert_to(value, type)
  return value unless type

  succeed, result = XlsFunction::Converter.try_convert_to(type, value)
  succeed ? result : XlsFunction::ErrorValue.value!(class_info(result))
end

#detect_error(value) ⇒ Object



80
81
82
83
84
# File 'lib/xls_function/evaluators/function_evaluator.rb', line 80

def detect_error(value)
  return unless value.is_a?(XlsFunction::ErrorValue)

  @error_value = value
end

#error?Boolean

Returns:

  • (Boolean)


86
87
88
# File 'lib/xls_function/evaluators/function_evaluator.rb', line 86

def error?
  !!error_value
end

#error_message(key, **placeholders) ⇒ Object



98
99
100
# File 'lib/xls_function/evaluators/function_evaluator.rb', line 98

def error_message(key, **placeholders)
  I18n.t("xls_function.errors.#{key}", **placeholders)
end

#eval_arglistObject



37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/xls_function/evaluators/function_evaluator.rb', line 37

def eval_arglist
  definitions = self.class.arg_definitions
  return if definitions.empty?

  definitions.zip(arg_list).each do |(name, default, type), arg|
    value = arg ? evaluate_or_self(arg) : default
    value = convert_to(value, type)
    instance_variable_set(:"@#{name}", value)
    detect_error(value)
    break if error?
  end
end

#eval_or_map_evalObject



61
62
63
64
65
66
67
68
# File 'lib/xls_function/evaluators/function_evaluator.rb', line 61

def eval_or_map_eval
  args = defined_args
  if args.any? { |arg| arg.is_a?(Array) }
    map_eval(args)
  else
    eval
  end
end

#evaluate(runtime_context = nil) ⇒ Object



21
22
23
24
25
26
27
28
29
30
31
# File 'lib/xls_function/evaluators/function_evaluator.rb', line 21

def evaluate(runtime_context = nil)
  rescue_with StandardError do
    merge_context(runtime_context) do
      before_eval
      # Don't evaluate when returns error
      return error_value if error?

      eval_or_map_eval
    end
  end
end

#evaluate_or_self(arg) ⇒ Object



50
51
52
# File 'lib/xls_function/evaluators/function_evaluator.rb', line 50

def evaluate_or_self(arg)
  arg.respond_to?(:evaluate) ? arg.evaluate(context) : arg
end

#map_eval(args) ⇒ Object



70
71
72
73
74
75
76
77
78
# File 'lib/xls_function/evaluators/function_evaluator.rb', line 70

def map_eval(args)
  arg_array = args.map { |x| Array(x) }
                  .then { |xs| xs.length == 1 ? xs : xs[0].product(*xs[1..]) }
  return XlsFunction::ErrorValue.na(class_info(error_message(:invalid_value_for_function))) if arg_array.max_depth > 2

  arg_array.map do |arg|
    to_proc.call(*arg) # Executes each created arguments as argument of self.
  end
end

#to_procObject



94
95
96
# File 'lib/xls_function/evaluators/function_evaluator.rb', line 94

def to_proc
  self.class.to_proc(context)
end

#variant_contextObject



90
91
92
# File 'lib/xls_function/evaluators/function_evaluator.rb', line 90

def variant_context
  context[:variants]
end