class Puppet::Pops::MergeStrategy
Merges to objects into one based on an implemented strategy.
Constants
- NOT_FOUND
Public Class Methods
Adds a new merge strategy to the map of strategies known to this class
@param strategy_class [Class<MergeStrategy>] The class of the added strategy
# File lib/puppet/pops/merge_strategy.rb 54 def self.add_strategy(strategy_class) 55 unless MergeStrategy > strategy_class 56 #TRANSLATORS 'MergeStrategies.add_strategy' is a method, 'stratgey_class' is a variable and 'MergeStrategy' is a class name and should not be translated 57 raise ArgumentError, _("MergeStrategies.add_strategy 'strategy_class' must be a 'MergeStrategy' class. Got %{strategy_class}") % 58 { strategy_class: strategy_class } 59 end 60 strategies[strategy_class.key] = strategy_class 61 nil 62 end
# File lib/puppet/pops/merge_strategy.rb 74 def self.key 75 raise NotImplementedError, "Subclass must implement 'key'" 76 end
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.
@param e1 [Object] The first element @param e2 [Object] The second element @return [Object] The result of the merge
# File lib/puppet/pops/merge_strategy.rb 70 def self.merge(e1, e2, merge) 71 strategy(merge).merge(e1, e2) 72 end
Create a new instance of this strategy configured with the given options @param merge_options [Hash<String,Object>] Merge options
# File lib/puppet/pops/merge_strategy.rb 80 def initialize(options) 81 assert_type('The merge options', self.class.options_t, options) unless options.empty? 82 @options = options 83 end
Finds the merge strategy for the given merge, creates an instance of it and returns that instance.
@param merge [MergeStrategy,String,Hash<String,Object>,nil] The merge strategy. Can be a string or symbol denoting the key
identifier or a hash with options where the key 'strategy' denotes the key
@return [MergeStrategy] The matching merge strategy
# File lib/puppet/pops/merge_strategy.rb 21 def self.strategy(merge) 22 return DefaultMergeStrategy::INSTANCE unless merge 23 return merge if merge.is_a?(MergeStrategy) 24 25 if merge.is_a?(Hash) 26 merge_strategy = merge['strategy'] 27 if merge_strategy.nil? 28 #TRANSLATORS 'merge' is a variable name and 'strategy' is a key and should not be translated 29 raise ArgumentError, _("The hash given as 'merge' must contain the name of a strategy in string form for the key 'strategy'") 30 end 31 merge_options = merge.size == 1 ? EMPTY_HASH : merge 32 else 33 merge_strategy = merge 34 merge_options = EMPTY_HASH 35 end 36 merge_strategy = merge_strategy.to_sym if merge_strategy.is_a?(String) 37 strategy_class = strategies[merge_strategy] 38 raise ArgumentError, _("Unknown merge strategy: '%{strategy}'") % { strategy: merge_strategy } if strategy_class.nil? 39 merge_options == EMPTY_HASH ? strategy_class::INSTANCE : strategy_class.new(merge_options) 40 end
Returns the list of merge strategy keys known to this class
@return [Array<Symbol>] List of strategy keys
# File lib/puppet/pops/merge_strategy.rb 46 def self.strategy_keys 47 strategies.keys - [:default, :unconstrained_deep, :reverse_deep] 48 end
Protected Class Methods
Returns the type used to validate the options hash
@return [Types::PStructType] the puppet type
# File lib/puppet/pops/merge_strategy.rb 182 def options_t 183 @options_t ||=Types::TypeParser.singleton.parse("Struct[{strategy=>Optional[Pattern[/#{key}/]]}]") 184 end
Private Class Methods
# File lib/puppet/pops/merge_strategy.rb 10 def self.strategies 11 @@strategies ||= {} 12 end
Public Instance Methods
# File lib/puppet/pops/merge_strategy.rb 167 def configuration 168 if @options.nil? || @options.empty? 169 self.class.key.to_s 170 else 171 @options.include?('strategy') ? @options : { 'strategy' => self.class.key.to_s }.merge(@options) 172 end 173 end
Converts a single value to the type expected when merging two elements @param value [Object] the value to convert @return [Object] the converted value
# File lib/puppet/pops/merge_strategy.rb 152 def convert_value(value) 153 value 154 end
Merges the result of yielding the given lookup_variants to a given block.
@param lookup_variants [Array] The variants to pass as second argument to the given block @return [Object] the merged value. @yield [} ] @yieldparam variant [Object] each variant given in the lookup_variants array. @yieldreturn [Object] the value to merge with other values @throws :no_such_key if the lookup was unsuccessful
Merges the result of yielding the given lookup_variants to a given block.
@param lookup_variants [Array] The variants to pass as second argument to the given block @return [Object] the merged value. @yield [} ] @yieldparam variant [Object] each variant given in the lookup_variants array. @yieldreturn [Object] the value to merge with other values @throws :no_such_key if the lookup was unsuccessful
# File lib/puppet/pops/merge_strategy.rb 122 def lookup(lookup_variants, lookup_invocation) 123 case lookup_variants.size 124 when 0 125 throw :no_such_key 126 when 1 127 merge_single(yield(lookup_variants[0])) 128 else 129 lookup_invocation.with(:merge, self) do 130 result = lookup_variants.reduce(NOT_FOUND) do |memo, lookup_variant| 131 not_found = true 132 value = catch(:no_such_key) do 133 v = yield(lookup_variant) 134 not_found = false 135 v 136 end 137 if not_found 138 memo 139 else 140 memo.equal?(NOT_FOUND) ? convert_value(value) : merge(memo, value) 141 end 142 end 143 throw :no_such_key if result == NOT_FOUND 144 lookup_invocation.report_result(result) 145 end 146 end 147 end
Merges the elements of e1 and e2 according to the rules of this strategy and options given when this instance was created
@param e1 [Object] The first element @param e2 [Object] The second element @return [Object] The result of the merge
# File lib/puppet/pops/merge_strategy.rb 92 def merge(e1, e2) 93 checked_merge( 94 assert_type('The first element of the merge', value_t, e1), 95 assert_type('The second element of the merge', value_t, e2)) 96 end
TODO: API 5.0 Remove this method @deprecated
# File lib/puppet/pops/merge_strategy.rb 100 def merge_lookup(lookup_variants) 101 lookup(lookup_variants, Lookup::Invocation.current) 102 end
Applies the merge strategy on a single element. Only applicable for `unique` @param value [Object] the value to merge with nothing @return [Object] the merged value
# File lib/puppet/pops/merge_strategy.rb 159 def merge_single(value) 160 value 161 end
# File lib/puppet/pops/merge_strategy.rb 163 def options 164 @options 165 end
Protected Instance Methods
# File lib/puppet/pops/merge_strategy.rb 199 def assert_type(param, type, value) 200 Types::TypeAsserter.assert_instance_of(param, type, value) 201 end
# File lib/puppet/pops/merge_strategy.rb 195 def checked_merge(e1, e2) 196 raise NotImplementedError, "Subclass must implement 'checked_merge(e1,e2)'" 197 end
Returns the type used to validate the options hash
@return [Types::PAnyType] the puppet type
# File lib/puppet/pops/merge_strategy.rb 191 def value_t 192 raise NotImplementedError, "Subclass must implement 'value_t'" 193 end