Module: Phronomy::Graph::State

Defined in:
lib/phronomy/graph/state.rb

Overview

Module for defining graph state. Include in a class and use the field DSL to declare state fields.

Field update policies: :replace (default) -- overwrites with the new value :append -- appends to an Array :merge -- deep-merges into a Hash

Examples:

class MyState
  include Phronomy::Graph::State
  field :messages, type: :append, default: -> { [] }
  field :query,    type: :replace
  field :metadata, type: :merge,   default: -> { {} }
end

Defined Under Namespace

Modules: ClassMethods

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#current_nodesObject (readonly)

Internal graph metadata accessors (not user-defined fields). These are preserved through merge but excluded from to_h.



43
44
45
# File 'lib/phronomy/graph/state.rb', line 43

def current_nodes
  @current_nodes
end

#halted_beforeObject (readonly)

Internal graph metadata accessors (not user-defined fields). These are preserved through merge but excluded from to_h.



43
44
45
# File 'lib/phronomy/graph/state.rb', line 43

def halted_before
  @halted_before
end

#thread_idObject (readonly)

Internal graph metadata accessors (not user-defined fields). These are preserved through merge but excluded from to_h.



43
44
45
# File 'lib/phronomy/graph/state.rb', line 43

def thread_id
  @thread_id
end

Class Method Details

.included(base) ⇒ Object



21
22
23
24
# File 'lib/phronomy/graph/state.rb', line 21

def self.included(base)
  base.extend(ClassMethods)
  base.instance_variable_set(:@fields, {})
end

Instance Method Details

#initialize(**attrs) ⇒ Object



56
57
58
59
60
61
62
63
64
# File 'lib/phronomy/graph/state.rb', line 56

def initialize(**attrs)
  self.class.fields.each do |name, config|
    default = config[:default].is_a?(Proc) ? config[:default].call : config[:default]
    send(:"#{name}=", attrs.fetch(name, default))
  end
  @thread_id = nil
  @current_nodes = []
  @halted_before = false
end

#merge(updates) ⇒ self.class

Immutably updates state fields. Returns a new instance with the applied changes. Internal graph metadata (thread_id, current_nodes, halted_before) is preserved.

Parameters:

  • updates (Hash)

    { field_name => new_value }

Returns:

  • (self.class)

    new state instance



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/phronomy/graph/state.rb', line 70

def merge(updates)
  new_attrs = {}
  self.class.fields.each_key do |name|
    field_config = self.class.fields[name]
    new_attrs[name] = if updates.key?(name)
      case field_config[:type]
      when :append
        Array(send(name)) + Array(updates[name])
      when :merge
        (send(name) || {}).merge(updates[name])
      else
        updates[name]
      end
    else
      send(name)
    end
  end
  new_state = self.class.new(**new_attrs)
  new_state.(
    thread_id: @thread_id,
    current_nodes: @current_nodes,
    halted_before: @halted_before
  )
  new_state
end

#set_graph_metadata(thread_id: nil, current_nodes: [], halted_before: false) ⇒ Object

Sets internal graph metadata. Returns self.

Parameters:

  • thread_id (String, nil) (defaults to: nil)
  • current_nodes (Array<Symbol>) (defaults to: [])
  • halted_before (Boolean) (defaults to: false)


49
50
51
52
53
54
# File 'lib/phronomy/graph/state.rb', line 49

def (thread_id: nil, current_nodes: [], halted_before: false)
  @thread_id = thread_id
  @current_nodes = current_nodes || []
  @halted_before = halted_before
  self
end

#to_hHash

Converts user-defined fields to a Hash (excludes internal graph metadata).

Returns:

  • (Hash)


98
99
100
101
102
# File 'lib/phronomy/graph/state.rb', line 98

def to_h
  self.class.fields.keys.each_with_object({}) do |name, h|
    h[name] = send(name)
  end
end