Module: AppMap::ValueInspector

Extended by:
ValueInspector
Included in:
Event::MethodEvent, ValueInspector
Defined in:
lib/appmap/value_inspector.rb

Constant Summary collapse

MAX_DEPTH =
3

Instance Method Summary collapse

Instance Method Details

#best_class_name(value) ⇒ Object

Heuristic for dynamically defined class whose name can be nil



41
42
43
44
45
46
47
# File 'lib/appmap/value_inspector.rb', line 41

def best_class_name(value)
  value_cls = value.class
  while value_cls && value_cls.name.nil?
    value_cls = value_cls.superclass
  end
  value_cls&.name || 'unknown'
end

#detect_schema(value, max_depth: MAX_DEPTH, type_info: {}, observed_values: Set.new(), depth: 0) ⇒ Object



14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/appmap/value_inspector.rb', line 14

def detect_schema(value, max_depth: MAX_DEPTH, type_info: {}, observed_values: Set.new(), depth: 0)
  return type_info if depth == max_depth

  begin
    if value.respond_to?(:keys)
      properties = value.keys.select { |key| key != '' && !key.nil? }.map do |key|
        next_value = value[key]
        next if observed_values.include?(next_value)

        observed_values << next_value
        { name: key, class: best_class_name(next_value) }.tap do |schema|
          detect_schema(next_value, **{ max_depth: max_depth, type_info: schema, observed_values: observed_values, depth: depth + 1 })
        end
      end.compact
      type_info[:properties] = properties unless properties.empty?
    elsif value.respond_to?(:first) && !observed_values.include?(value.first)
      observed_values << value.first
      detect_schema(value.first, **{ max_depth: max_depth, type_info: type_info, observed_values: observed_values, depth: depth + 1 })
    end
  rescue
    warn "Error in add_schema(#{value.class})", $!
    raise
  end
  type_info
end

#detect_size(value) ⇒ Object



7
8
9
10
11
12
# File 'lib/appmap/value_inspector.rb', line 7

def detect_size(value)
  # Don't risk calling #size on things like data-access objects, which can and will issue queries for this information.
  if value.is_a?(Array) || value.is_a?(Hash)
    value.size
  end
end