Class: WaterDrop::Configurable::Node

Inherits:
Object
  • Object
show all
Defined in:
lib/waterdrop/configurable/node.rb

Overview

Single non-leaf node This is a core component for the configurable settings

The idea here is simple: we collect settings (leafs) and children (nodes) information and we only compile/initialize the values prior to user running the `#configure` API. This API needs to run prior to using the result stuff even if there is nothing to configure

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name, nestings = ->(_) {}) ⇒ Node

Returns a new instance of Node.

Parameters:

  • name (Symbol)

    node name

  • nestings (Proc) (defaults to: ->(_) {})

    block for nested settings



19
20
21
22
23
24
# File 'lib/waterdrop/configurable/node.rb', line 19

def initialize(name, nestings = ->(_) {})
  @name = name
  @children = []
  @nestings = nestings
  instance_eval(&nestings)
end

Instance Attribute Details

#childrenObject

We need to be able to redefine children for deep copy



15
16
17
# File 'lib/waterdrop/configurable/node.rb', line 15

def children
  @children
end

#nameObject (readonly)

Returns the value of attribute name.



12
13
14
# File 'lib/waterdrop/configurable/node.rb', line 12

def name
  @name
end

#nestingsObject (readonly)

Returns the value of attribute nestings.



12
13
14
# File 'lib/waterdrop/configurable/node.rb', line 12

def nestings
  @nestings
end

Instance Method Details

#compileObject

Note:

It runs once, after things are compiled, they will not be recompiled again

Converts the settings definitions into end children



80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/waterdrop/configurable/node.rb', line 80

def compile
  @children.each do |value|
    # Do not redefine something that was already set during compilation
    # This will allow us to reconfigure things and skip override with defaults
    next if respond_to?(value.name)

    singleton_class.attr_accessor value.name

    initialized = if value.is_a?(Leaf)
                    value.constructor ? value.constructor.call(value.default) : value.default
                  else
                    value.compile
                    value
                  end

    public_send("#{value.name}=", initialized)
  end
end

#configure {|_self| ... } ⇒ Node

Allows for the configuration and setup of the settings

Compile settings, allow for overrides via yielding

Yields:

  • (_self)

Yield Parameters:

Returns:

  • (Node)

    returns self after configuration



44
45
46
47
48
# File 'lib/waterdrop/configurable/node.rb', line 44

def configure
  compile
  yield(self) if block_given?
  self
end

#deep_dupNode

Deep copies all the children nodes to allow us for templates building on a class level and non-side-effect usage on an instance/inherited.

Returns:

  • (Node)

    duplicated node



68
69
70
71
72
73
74
75
76
# File 'lib/waterdrop/configurable/node.rb', line 68

def deep_dup
  dupped = Node.new(name, nestings)

  dupped.children += children.map do |value|
    value.is_a?(Leaf) ? value.dup : value.deep_dup
  end

  dupped
end

#setting(name, default: nil, constructor: nil, &block) ⇒ Object

Allows for a single leaf or nested node definition

Parameters:

  • name (Symbol)

    setting or nested node name

  • default (Object) (defaults to: nil)

    default value

  • constructor (#call, nil) (defaults to: nil)

    callable or nil

  • block (Proc)

    block for nested settings



32
33
34
35
36
37
38
# File 'lib/waterdrop/configurable/node.rb', line 32

def setting(name, default: nil, constructor: nil, &block)
  @children << if block
                 Node.new(name, block)
               else
                 Leaf.new(name, default, constructor)
               end
end

#to_hHash

Returns frozen config hash representation.

Returns:

  • (Hash)

    frozen config hash representation



51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/waterdrop/configurable/node.rb', line 51

def to_h
  config = {}

  @children.each do |value|
    config[value.name] = if value.is_a?(Leaf)
                           public_send(value.name)
                         else
                           value.to_h
                         end
  end

  config.freeze
end