Class: Datadog::DI::EL::Evaluator Private

Inherits:
Object
  • Object
show all
Defined in:
lib/datadog/di/el/evaluator.rb

Overview

This class is part of a private API. You should avoid using this class if possible, as it may be removed or be changed in the future.

Evaluator for expression language.

Constant Summary collapse

MATCHES_TIMEOUT_SECONDS =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

Maximum wall-clock time allowed for evaluating a single matches operator.

0.5

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(regexps = []) ⇒ Evaluator

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns a new instance of Evaluator.

Parameters:

  • regexps (Array<Regexp>) (defaults to: [])

    Regexps precompiled from literal matches patterns, looked up by index by #matches_compiled. Empty when the expression has no matches pattern with a direct regular expression argument.



22
23
24
# File 'lib/datadog/di/el/evaluator.rb', line 22

def initialize(regexps = [])
  @regexps = regexps
end

Instance Attribute Details

#regexpsObject (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



26
27
28
# File 'lib/datadog/di/el/evaluator.rb', line 26

def regexps
  @regexps
end

Class Method Details

.compile_regexp(needle) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



80
81
82
# File 'lib/datadog/di/el/evaluator.rb', line 80

def self.compile_regexp(needle)
  Regexp.new(needle, timeout: MATCHES_TIMEOUT_SECONDS)
end

Instance Method Details

#all(collection, &block) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
# File 'lib/datadog/di/el/evaluator.rb', line 174

def all(collection, &block)
  case collection
  when Array
    collection.all? do |item|
      block.call(item)
    end
  when Hash
    # For hashes, the expression language has both @it and
    # @key/@value. Manufacture @it from the key and value.
    collection.all? do |key, value|
      block.call([key, value], key, value)
    end
  else
    raise DI::Error::ExpressionEvaluationError, "Bad collection type for all: #{collection.class}"
  end
end

#any(collection, &block) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
# File 'lib/datadog/di/el/evaluator.rb', line 191

def any(collection, &block)
  case collection
  when Array
    collection.any? do |item|
      block.call(item)
    end
  when Hash
    collection.any? do |key, value|
      # For hashes, the expression language has both @it and
      # @key/@value. Manufacture @it from the key and value.
      block.call([key, value], key, value)
    end
  else
    raise DI::Error::ExpressionEvaluationError, "Bad collection type for any: #{collection.class}"
  end
end

#contains(haystack, needle) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



60
61
62
63
64
65
66
67
# File 'lib/datadog/di/el/evaluator.rb', line 60

def contains(haystack, needle)
  if String === haystack && String === needle or # standard:disable Style/AndOr
      Array === haystack
    haystack.include?(needle)
  else
    raise DI::Error::ExpressionEvaluationError, "Invalid arguments for contains: #{haystack}, #{needle}"
  end
end

#ends_with(haystack, needle) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



170
171
172
# File 'lib/datadog/di/el/evaluator.rb', line 170

def ends_with(haystack, needle)
  String === haystack && haystack.end_with?(needle)
end

#filter(collection, &block) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



208
209
210
211
212
213
214
215
216
217
218
219
220
221
# File 'lib/datadog/di/el/evaluator.rb', line 208

def filter(collection, &block)
  case collection
  when Array
    collection.select do |item|
      block.call(item)
    end
  when Hash
    collection.select do |key, value|
      block.call([key, value], key, value)
    end.to_h
  else
    raise DI::Error::ExpressionEvaluationError, "Bad collection type for filter: #{collection.class}"
  end
end

#getmember(object, field) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



136
137
138
# File 'lib/datadog/di/el/evaluator.rb', line 136

def getmember(object, field)
  object.instance_variable_get("@#{field}")
end

#index(array_or_hash, index_or_key) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/datadog/di/el/evaluator.rb', line 140

def index(array_or_hash, index_or_key)
  case array_or_hash
  when Array
    case index_or_key
    when Integer
      array_or_hash[index_or_key]
    else
      raise DI::Error::ExpressionEvaluationError, "Invalid index value: #{index_or_key}"
    end
  when Hash
    array_or_hash[index_or_key]
  else
    raise DI::Error::ExpressionEvaluationError, "Invalid argument for index: #{array_or_hash}"
  end
end

#instanceof(object, cls_name) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



223
224
225
226
227
228
229
230
231
232
233
234
235
# File 'lib/datadog/di/el/evaluator.rb', line 223

def instanceof(object, cls_name)
  cls = object.class
  loop do
    if cls.name == cls_name
      return true
    end
    if supercls = cls.superclass # standard:disable Lint/AssignmentInCondition
      cls = supercls
    else
      return false
    end
  end
end

#iref(var) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



32
33
34
# File 'lib/datadog/di/el/evaluator.rb', line 32

def iref(var)
  @context.fetch_ivar(var)
end

#is_empty(var, var_name) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



45
46
47
48
49
50
51
52
53
54
# File 'lib/datadog/di/el/evaluator.rb', line 45

def is_empty(var, var_name)
  case var
  when nil, Numeric
    false
  when Array, String
    var.empty?
  else
    raise DI::Error::ExpressionEvaluationError, "Unsupported type for isEmpty: #{var.class}: #{var_name}"
  end
end

#is_undefined(var, var_name) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



56
57
58
# File 'lib/datadog/di/el/evaluator.rb', line 56

def is_undefined(var, var_name)
  var.nil?
end

#len(var, var_name) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



36
37
38
39
40
41
42
43
# File 'lib/datadog/di/el/evaluator.rb', line 36

def len(var, var_name)
  case var
  when Array, String, Hash
    var.length
  else
    raise DI::Error::ExpressionEvaluationError, "Unsupported type for length: #{var.class}: #{var_name}"
  end
end

#matches(haystack, needle) ⇒ Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Match haystack against a regexp whose needle is computed at evaluation time, so the Regexp cannot be precompiled. Literal needles are precompiled by the Compiler and dispatched to #matches_compiled.

Parameters:

  • haystack (String)

    string to match against.

  • needle (String)

    regexp source.

Returns:

  • (Boolean)

    whether the haystack matches the regexp.

Raises:

  • (Regexp::TimeoutError)

    (Ruby 3.2+) regexp engine exceeded MATCHES_TIMEOUT_SECONDS.

  • (Timeout::Error)

    (Ruby < 3.2) Timeout.timeout fired.



98
99
100
# File 'lib/datadog/di/el/evaluator.rb', line 98

def matches(haystack, needle)
  bounded_match?(Evaluator.compile_regexp(needle), haystack)
end

#matches_compiled(haystack, index) ⇒ Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Match haystack against a Regexp precompiled at expression-compile time, looked up by index in regexps.

Parameters:

  • haystack (String)

    string to match against.

  • index (Integer)

    position of the precompiled Regexp in regexps.

Returns:

  • (Boolean)

    whether the haystack matches the regexp.

Raises:

  • (Regexp::TimeoutError)

    (Ruby 3.2+) regexp engine exceeded MATCHES_TIMEOUT_SECONDS.

  • (Timeout::Error)

    (Ruby < 3.2) Timeout.timeout fired.



110
111
112
# File 'lib/datadog/di/el/evaluator.rb', line 110

def matches_compiled(haystack, index)
  bounded_match?(regexps.fetch(index), haystack)
end

#ref(var) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



28
29
30
# File 'lib/datadog/di/el/evaluator.rb', line 28

def ref(var)
  @context.fetch(var)
end

#starts_with(haystack, needle) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



163
164
165
166
167
168
# File 'lib/datadog/di/el/evaluator.rb', line 163

def starts_with(haystack, needle)
  # To guard against running arbitrary customer code, check that
  # the haystack is a string. This does not help if customer
  # overrode String#start_with? but at least it's better than nothing.
  String === haystack && haystack.start_with?(needle)
end

#substring(object, from, to) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



156
157
158
159
160
161
# File 'lib/datadog/di/el/evaluator.rb', line 156

def substring(object, from, to)
  unless String === object
    raise DI::Error::ExpressionEvaluationError, "Invalid type for substring: #{object}"
  end
  object[from...to]
end