Class: Factrey::Blueprint::Node

Inherits:
Object
  • Object
show all
Defined in:
lib/factrey/blueprint/node.rb

Overview

A node corresponds to an object to be created. A Factrey::Blueprint consists of a set of nodes.

Constant Summary collapse

ANONYMOUS_NAME_PREFIX =

A name prefix given to anonymous nodes for convenience.

"_anon_"
RESULT_NAME =

Name used for the node that hold the results of the blueprint.

:_result_

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name, type, parent: nil, args: [], kwargs: {}) ⇒ Node

Returns a new instance of Node.

Raises:

  • (TypeError)


25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/factrey/blueprint/node.rb', line 25

def initialize(name, type, parent: nil, args: [], kwargs: {})
  raise TypeError, "name must be a Symbol" if name && !name.is_a?(Symbol)
  raise TypeError, "type must be a Blueprint::Type" unless type.is_a? Blueprint::Type
  raise TypeError, "parent must be a Node" if parent && !parent.is_a?(Node)
  raise TypeError, "args must be an Array" unless args.is_a? Array
  raise TypeError, "kwargs must be a Hash" unless kwargs.is_a? Hash

  @name = name || :"#{ANONYMOUS_NAME_PREFIX}#{SecureRandom.hex(6)}"
  @type = type
  @parent = parent
  @args = args
  @kwargs = kwargs
end

Instance Attribute Details

#argsArray<Object> (readonly)

Returns positional arguments to be passed to the factory.

Returns:

  • (Array<Object>)

    positional arguments to be passed to the factory



21
22
23
# File 'lib/factrey/blueprint/node.rb', line 21

def args
  @args
end

#kwargsHash{Object => Object} (readonly)

Returns keyword arguments to be passed to the factory.

Returns:

  • (Hash{Object => Object})

    keyword arguments to be passed to the factory



23
24
25
# File 'lib/factrey/blueprint/node.rb', line 23

def kwargs
  @kwargs
end

#nameSymbol (readonly)

Returns name given to the object to be created.

Returns:

  • (Symbol)

    name given to the object to be created



15
16
17
# File 'lib/factrey/blueprint/node.rb', line 15

def name
  @name
end

#parentNode? (readonly)

Returns parent node.

Returns:

  • (Node, nil)

    parent node



19
20
21
# File 'lib/factrey/blueprint/node.rb', line 19

def parent
  @parent
end

#typeType (readonly)

Returns type of the object.

Returns:

  • (Type)

    type of the object



17
18
19
# File 'lib/factrey/blueprint/node.rb', line 17

def type
  @type
end

Class Method Details

.computed(name, value, parent: nil) ⇒ Object

Parameters:

  • name (Symbol, nil)
  • value (Object)
  • parent (Node, nil) (defaults to: nil)


42
43
44
# File 'lib/factrey/blueprint/node.rb', line 42

def self.computed(name, value, parent: nil)
  new(name, Blueprint::Type::COMPUTED, parent:, args: [value])
end

Instance Method Details

#alias_refRef?

Returns if this node works as an alias to another node, return the reference to the node.

Returns:

  • (Ref, nil)

    if this node works as an alias to another node, return the reference to the node



56
57
58
59
60
61
62
63
# File 'lib/factrey/blueprint/node.rb', line 56

def alias_ref
  case [type, args]
  in Blueprint::Type::COMPUTED, [Ref => ref]
    ref
  else
    nil
  end
end

#ancestorsArray<Node>

Returns a list of ancestor nodes.

Returns:

  • (Array<Node>)

    a list of ancestor nodes



66
# File 'lib/factrey/blueprint/node.rb', line 66

def ancestors = parent ? [parent].concat(parent.ancestors) : []

#anonymous?Boolean

Returns:

  • (Boolean)


47
# File 'lib/factrey/blueprint/node.rb', line 47

def anonymous? = name.start_with?(ANONYMOUS_NAME_PREFIX)

#auto_referenced_ancestorsHash{Symbol => Node}

Returns a map from attributes to auto-referenced ancestor nodes.

Returns:

  • (Hash{Symbol => Node})

    a map from attributes to auto-referenced ancestor nodes



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/factrey/blueprint/node.rb', line 69

def auto_referenced_ancestors
  ancestors = self.ancestors
  candidates = {}
  type.auto_references.each do |type_name, attribute|
    next if kwargs.member? attribute # this attribute is explicitly specified

    # closer ancestors have higher (lower integer) priority
    compatible_node, priority = ancestors.each_with_index.find do |node, _|
      node.type.compatible_types.include?(type_name)
    end
    next unless compatible_node
    next if candidates.member?(attribute) && candidates[attribute][0] <= priority

    candidates[attribute] = [priority, compatible_node]
  end

  candidates.transform_values { _2 }
end

#result?Boolean

Returns:

  • (Boolean)


50
# File 'lib/factrey/blueprint/node.rb', line 50

def result? = name == RESULT_NAME

#to_refRef

Returns the reference to this node.

Returns:

  • (Ref)

    the reference to this node



53
# File 'lib/factrey/blueprint/node.rb', line 53

def to_ref = Ref.new(name)

#type_annotated_nameString

Used for debugging and error reporting.

Returns:

  • (String)


90
# File 'lib/factrey/blueprint/node.rb', line 90

def type_annotated_name = "#{name}(#{type.name})"