Class: PDK::Config::Setting

Inherits:
Object
  • Object
show all
Defined in:
lib/pdk/config/setting.rb

Overview

A class for describing the setting of a PDK::Config setting.

Generally, this is never instantiated manually, but is instead instantiated by passing a block to Namespace#setting.

PDK::Config::Namespace.new(‘module_defaults’) do

setting :author do
  validate PDK::Config::Validator.string
  default_to { false }
end

end

Direct Known Subclasses

IniFileSetting, JSONSchemaSetting

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name, namespace, initial_value = nil) ⇒ Setting

Initialises an empty setting definition.

Parameters:

  • name (String, Symbol)

    the name of the setting.

  • namespace (PDK::Config::Namespace)

    The namespace this setting belongs to



38
39
40
41
42
43
# File 'lib/pdk/config/setting.rb', line 38

def initialize(name, namespace, initial_value = nil)
  @name = name.to_s
  @validators = []
  @namespace = namespace
  @value = initial_value
end

Instance Attribute Details

#namespaceObject (readonly)

Returns the value of attribute namespace.



19
20
21
# File 'lib/pdk/config/setting.rb', line 19

def namespace
  @namespace
end

#previous_setting=(value) ⇒ Object (writeonly)

It is possible to have multiple setting definitions for the same setting; for example, defining a default value with a lambda, but the the validation is within a JSON schema document. These are expressed as two settings objects, and uses a single linked list to join them together:

(PDK::Config::JSONSchemaSetting) –previous_setting–> (PDK::Config::Setting)

So in the example above, calling ‘default` the on the first object in the list will:

  1. Look at ‘default` on PDK::Config::JSONSchemaSetting

  2. If a default could not be found then it calls ‘default` on previous_setting

  3. If a default could not be found then it calls ‘default` on previous_setting.previous_setting

  4. and so on down the linked list (chain) of settings



32
33
34
# File 'lib/pdk/config/setting.rb', line 32

def previous_setting=(value)
  @previous_setting = value
end

Instance Method Details

#defaultObject?

Evaluate the default setting.

Returns:

  • (Object, nil)

    the result of evaluating the block given to #default_to, or ‘nil` if the setting has no default.



119
120
121
122
123
124
# File 'lib/pdk/config/setting.rb', line 119

def default
  return @default_to.call if default_block?

  # If there is a previous setting in the chain, use its default
  @previous_setting&.default
end

#default_to(&block) ⇒ nil

Assign a default value proc for the setting. Subclasses should not override this method.

Parameters:

  • block (Proc)

    a block that is lazy evaluated when necessary in order to determine the default setting.

Returns:

  • (nil)

Raises:

  • (ArgumentError)


109
110
111
112
113
# File 'lib/pdk/config/setting.rb', line 109

def default_to(&block)
  raise ArgumentError, 'must be passed a block' unless block

  @default_to = block
end

#qualified_nameObject



45
46
47
# File 'lib/pdk/config/setting.rb', line 45

def qualified_name
  [namespace.name, @name].join('.')
end

#to_sObject



59
60
61
# File 'lib/pdk/config/setting.rb', line 59

def to_s
  @value.to_s
end

#validate(validator) ⇒ nil

Assign a validator to the setting. Subclasses should not override this method.

Parameters:

  • validator (Hash{Symbol => [Proc,String]})

Options Hash (validator):

  • :proc (Proc)

    a lambda that takes the setting to be validated as the argument and returns ‘true` if the setting is valid.

  • :message (String)

    a description of what the validator is testing for, that is displayed to the user as part of the error message for invalid settings.

Returns:

  • (nil)

Raises:

  • (ArgumentError)

    if not passed a Hash.

  • (ArgumentError)

    if the Hash doesn’t have a ‘:proc` key that contains a Proc.

  • (ArgumentError)

    if the Hash doesn’t have a ‘:message` key that contains a String.



79
80
81
82
83
84
85
# File 'lib/pdk/config/setting.rb', line 79

def validate(validator)
  raise ArgumentError, '`validator` must be a Hash' unless validator.is_a?(Hash)
  raise ArgumentError, 'the :proc key must contain a Proc' unless validator.key?(:proc) && validator[:proc].is_a?(Proc)
  raise ArgumentError, 'the :message key must contain a String' unless validator.key?(:message) && validator[:message].is_a?(String)

  @validators << validator
end

#validate!(value) ⇒ nil

Validate a setting against the assigned validators.

Parameters:

  • setting (Object)

    the setting being validated.

Returns:

  • (nil)

Raises:

  • (ArgumentError)

    if any of the assigned validators fail to validate the setting.



95
96
97
98
99
100
101
# File 'lib/pdk/config/setting.rb', line 95

def validate!(value)
  @validators.each do |validator|
    next if validator[:proc].call(value)

    raise ArgumentError, format('%{key} %{message}', key: qualified_name, message: validator[:message])
  end
end

#valueObject



49
50
51
52
# File 'lib/pdk/config/setting.rb', line 49

def value
  # Duplicate arrays and hashes so that they are isolated from changes being made
  PDK::Util.deep_duplicate(@value)
end

#value=(obj) ⇒ Object



54
55
56
57
# File 'lib/pdk/config/setting.rb', line 54

def value=(obj)
  validate!(obj)
  @value = obj
end