Class: LazyGraph::ArrayNode

Inherits:
Node
  • Object
show all
Defined in:
lib/lazy_graph/node/array_node.rb

Constant Summary

Constants included from Node::DerivedRules

Node::DerivedRules::PLACEHOLDER_VAR_REGEX

Instance Attribute Summary

Attributes inherited from Node

#children, #depth, #derived, #invisible, #is_object, #name, #parent, #path, #root, #type

Instance Method Summary collapse

Methods inherited from Node

#absolute_path, #ancestors, #clear_visits!, #copy_item!, #define_missing_value_proc!, #derive_item!, #fetch_item, #find_resolver_for, #initialize, #lazy_init_node!, #resolve_input

Methods included from Node::DerivedRules

#build_derived_inputs, #create_derived_input_context, #extract_derived_src, extract_expr_from_source_location, #interpret_derived_proc, #map_derived_inputs_to_paths, #parse_args_with_conditions, #parse_derived_inputs, #parse_rule_string

Constructor Details

This class inherits a constructor from LazyGraph::Node

Instance Method Details

#cast(value) ⇒ Object



68
69
70
# File 'lib/lazy_graph/node/array_node.rb', line 68

def cast(value)
  value
end

#children=(value) ⇒ Object



63
64
65
66
# File 'lib/lazy_graph/node/array_node.rb', line 63

def children=(value)
  @children = value
  @child_properties = @children.children[:properties].compare_by_identity if @children.is_object
end

#resolve(path, stack_memory, should_recycle = stack_memory) ⇒ Object

An Array supports the following types of path resolutions.

  1. Forward property (assuming child items are objects): arr.property

  2. Absolute Index: arr, arr, arr, …

  3. Range: arr, arr

  4. All:arr [*]

  5. Set of indexes: arr[0, 2, 4]

Parts between square brackets are represented as path groups.



11
12
13
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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/lazy_graph/node/array_node.rb', line 11

def resolve(
  path,
  stack_memory,
  should_recycle = stack_memory,
  **
)
  input = stack_memory.frame
  @visited[input.object_id >> 2 ^ path.shifted_id] ||= begin
    if (path_segment = path.segment).is_a?(PathParser::PathGroup)
      unless path_segment.index?
        return input.length.times.map do |index|
          item = children.fetch_item(input, index, stack_memory)
          children.resolve(path, stack_memory.push(item, index))
        end
      end

      return resolve(path_segment.options.first.merge(path.next), stack_memory, nil) if path_segment.options.one?

      return path_segment.options.map { |part| resolve(part.merge(path.next), stack_memory, nil) }
    end

    segment = path_segment&.part
    case segment
    when nil
      input.length.times do |index|
        item = children.fetch_item(input, index, stack_memory)
        children.resolve(path, stack_memory.push(item, index))
      end
      input
    when DIGIT_REGEXP
      item = @children.fetch_item(input, segment.to_s.to_i, stack_memory)
      children.resolve(path.next, stack_memory.push(item, segment))
    when :*
      input.length.times.map do |index|
        item = children.fetch_item(input, index, stack_memory)
        @children.resolve(path.next, stack_memory.push(item, index))
      end
    else
      if @child_properties&.key?(segment) || input&.first&.key?(segment)
        input.length.times.map do |index|
          item = children.fetch_item(input, index, stack_memory)
          @children.resolve(path, stack_memory.push(item, index))
        end
      else
        MissingValue()
      end
    end
  end
ensure
  should_recycle&.recycle!
end