Class: Puppet::Pops::MergeStrategy

Inherits:
Object
  • Object
show all
Defined in:
lib/puppet/pops/merge_strategy.rb

Overview

Merges to objects into one based on an implemented strategy.

Constant Summary collapse

NOT_FOUND =
Object.new.freeze

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options) ⇒ MergeStrategy

Create a new instance of this strategy configured with the given options



76
77
78
79
# File 'lib/puppet/pops/merge_strategy.rb', line 76

def initialize(options)
  assert_type('The merge options', self.class.options_t, options) unless options.empty?
  @options = options
end

Class Method Details

.add_strategy(strategy_class) ⇒ Object

Adds a new merge strategy to the map of strategies known to this class



52
53
54
55
56
57
58
# File 'lib/puppet/pops/merge_strategy.rb', line 52

def self.add_strategy(strategy_class)
  unless MergeStrategy > strategy_class
    raise ArgumentError, "MergeStrategies.add_strategy 'strategy_class' must be a 'MergeStrategy' class. Got #{strategy_class}"
  end
  strategies[strategy_class.key] = strategy_class
  nil
end

.keyObject

Raises:

  • (NotImplementedError)


70
71
72
# File 'lib/puppet/pops/merge_strategy.rb', line 70

def self.key
  raise NotImplementedError, "Subclass must implement 'key'"
end

.merge(e1, e2, merge) ⇒ Object

Finds a merge strategy that corresponds to the given merge argument and delegates the task of merging the elements of e1 and e2 to it.



66
67
68
# File 'lib/puppet/pops/merge_strategy.rb', line 66

def self.merge(e1, e2, merge)
  strategy(merge).merge(e1, e2)
end

.strategy(merge) ⇒ MergeStrategy

Finds the merge strategy for the given merge, creates an instance of it and returns that instance.

Raises:

  • (ArgumentError)


20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/puppet/pops/merge_strategy.rb', line 20

def self.strategy(merge)
  return DefaultMergeStrategy::INSTANCE unless merge
  return merge if merge.is_a?(MergeStrategy)

  if merge.is_a?(Hash)
    merge_strategy = merge['strategy']
    if merge_strategy.nil?
      raise ArgumentError, "The hash given as 'merge' must contain the name of a strategy in string form for the key 'strategy'"
    end
    merge_options  = merge.size == 1 ? EMPTY_HASH : merge
  else
    merge_strategy = merge
    merge_options = EMPTY_HASH
  end
  merge_strategy = merge_strategy.to_sym if merge_strategy.is_a?(String)
  strategy_class = strategies[merge_strategy]
  raise ArgumentError, "Unknown merge strategy: '#{merge_strategy}'" if strategy_class.nil?
  merge_options == EMPTY_HASH ? strategy_class::INSTANCE : strategy_class.new(merge_options)
end

.strategy_keysArray<Symbol>

Returns the list of merge strategy keys known to this class



44
45
46
# File 'lib/puppet/pops/merge_strategy.rb', line 44

def self.strategy_keys
  strategies.keys - [:default, :unconstrained_deep, :reverse_deep]
end

Instance Method Details

#configurationObject



163
164
165
166
167
168
169
# File 'lib/puppet/pops/merge_strategy.rb', line 163

def configuration
  if @options.nil? || @options.empty?
    self.class.key.to_s
  else
    @options.include?('strategy') ? @options : { 'strategy' => self.class.key.to_s }.merge(@options)
  end
end

#convert_value(value) ⇒ Object

Converts a single value to the type expected when merging two elements



148
149
150
# File 'lib/puppet/pops/merge_strategy.rb', line 148

def convert_value(value)
  value
end

#lookup(lookup_variants, lookup_invocation) {|variant, variant| ... } ⇒ Object

Merges the result of yielding the given lookup_variants to a given block.

Merges the result of yielding the given lookup_variants to a given block.

Yields:

  • }
  • }

Yield Parameters:

  • variant (Object)

    each variant given in the lookup_variants array.

  • variant (Object)

    each variant given in the lookup_variants array.

Yield Returns:

  • (Object)

    the value to merge with other values

  • (Object)

    the value to merge with other values



118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
# File 'lib/puppet/pops/merge_strategy.rb', line 118

def lookup(lookup_variants, lookup_invocation)
  case lookup_variants.size
  when 0
    throw :no_such_key
  when 1
    merge_single(yield(lookup_variants[0]))
  else
    lookup_invocation.with(:merge, self) do
      result = lookup_variants.reduce(NOT_FOUND) do |memo, lookup_variant|
        not_found = true
        value = catch(:no_such_key) do
          v = yield(lookup_variant)
          not_found = false
          v
        end
        if not_found
          memo
        else
          memo.equal?(NOT_FOUND) ? convert_value(value) : merge(memo, value)
        end
      end
      throw :no_such_key if result == NOT_FOUND
      lookup_invocation.report_result(result)
    end
  end
end

#merge(e1, e2) ⇒ Object

Merges the elements of e1 and e2 according to the rules of this strategy and options given when this instance was created



88
89
90
91
92
# File 'lib/puppet/pops/merge_strategy.rb', line 88

def merge(e1, e2)
  checked_merge(
    assert_type('The first element of the merge', value_t, e1),
    assert_type('The second element of the merge', value_t, e2))
end

#merge_lookup(lookup_variants) ⇒ Object

Deprecated.

TODO: API 5.0 Remove this method



96
97
98
# File 'lib/puppet/pops/merge_strategy.rb', line 96

def merge_lookup(lookup_variants)
  lookup(lookup_variants, Lookup::Invocation.current)
end

#merge_single(value) ⇒ Object

Applies the merge strategy on a single element. Only applicable for ‘unique`



155
156
157
# File 'lib/puppet/pops/merge_strategy.rb', line 155

def merge_single(value)
  value
end

#optionsObject



159
160
161
# File 'lib/puppet/pops/merge_strategy.rb', line 159

def options
  @options
end