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 53 def self.add_strategy(strategy_class) 54 unless MergeStrategy > strategy_class 55 #TRANSLATORS 'MergeStrategies.add_strategy' is a method, 'stratgey_class' is a variable and 'MergeStrategy' is a class name and should not be translated 56 raise ArgumentError, _("MergeStrategies.add_strategy 'strategy_class' must be a 'MergeStrategy' class. Got %{strategy_class}") % 57 { strategy_class: strategy_class } 58 end 59 strategies[strategy_class.key] = strategy_class 60 nil 61 end
# File lib/puppet/pops/merge_strategy.rb 73 def self.key 74 raise NotImplementedError, "Subclass must implement 'key'" 75 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 69 def self.merge(e1, e2, merge) 70 strategy(merge).merge(e1, e2) 71 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 79 def initialize(options) 80 assert_type('The merge options', self.class.options_t, options) unless options.empty? 81 @options = options 82 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 20 def self.strategy(merge) 21 return DefaultMergeStrategy::INSTANCE unless merge 22 return merge if merge.is_a?(MergeStrategy) 23 24 if merge.is_a?(Hash) 25 merge_strategy = merge['strategy'] 26 if merge_strategy.nil? 27 #TRANSLATORS 'merge' is a variable name and 'strategy' is a key and should not be translated 28 raise ArgumentError, _("The hash given as 'merge' must contain the name of a strategy in string form for the key 'strategy'") 29 end 30 merge_options = merge.size == 1 ? EMPTY_HASH : merge 31 else 32 merge_strategy = merge 33 merge_options = EMPTY_HASH 34 end 35 merge_strategy = merge_strategy.to_sym if merge_strategy.is_a?(String) 36 strategy_class = strategies[merge_strategy] 37 raise ArgumentError, _("Unknown merge strategy: '%{strategy}'") % { strategy: merge_strategy } if strategy_class.nil? 38 merge_options == EMPTY_HASH ? strategy_class::INSTANCE : strategy_class.new(merge_options) 39 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 45 def self.strategy_keys 46 strategies.keys - [:default, :unconstrained_deep, :reverse_deep] 47 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 181 def options_t 182 @options_t ||=Types::TypeParser.singleton.parse("Struct[{strategy=>Optional[Pattern[/#{key}/]]}]") 183 end
Private Class Methods
# File lib/puppet/pops/merge_strategy.rb 9 def self.strategies 10 @@strategies ||= {} 11 end
Public Instance Methods
# File lib/puppet/pops/merge_strategy.rb 166 def configuration 167 if @options.nil? || @options.empty? 168 self.class.key.to_s 169 else 170 @options.include?('strategy') ? @options : { 'strategy' => self.class.key.to_s }.merge(@options) 171 end 172 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 151 def convert_value(value) 152 value 153 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 121 def lookup(lookup_variants, lookup_invocation) 122 case lookup_variants.size 123 when 0 124 throw :no_such_key 125 when 1 126 merge_single(yield(lookup_variants[0])) 127 else 128 lookup_invocation.with(:merge, self) do 129 result = lookup_variants.reduce(NOT_FOUND) do |memo, lookup_variant| 130 not_found = true 131 value = catch(:no_such_key) do 132 v = yield(lookup_variant) 133 not_found = false 134 v 135 end 136 if not_found 137 memo 138 else 139 memo.equal?(NOT_FOUND) ? convert_value(value) : merge(memo, value) 140 end 141 end 142 throw :no_such_key if result == NOT_FOUND 143 lookup_invocation.report_result(result) 144 end 145 end 146 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 91 def merge(e1, e2) 92 checked_merge( 93 assert_type('The first element of the merge', value_t, e1), 94 assert_type('The second element of the merge', value_t, e2)) 95 end
TODO: API 5.0 Remove this method @deprecated
# File lib/puppet/pops/merge_strategy.rb 99 def merge_lookup(lookup_variants) 100 lookup(lookup_variants, Lookup::Invocation.current) 101 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 158 def merge_single(value) 159 value 160 end
# File lib/puppet/pops/merge_strategy.rb 162 def options 163 @options 164 end
Protected Instance Methods
# File lib/puppet/pops/merge_strategy.rb 198 def assert_type(param, type, value) 199 Types::TypeAsserter.assert_instance_of(param, type, value) 200 end
# File lib/puppet/pops/merge_strategy.rb 194 def checked_merge(e1, e2) 195 raise NotImplementedError, "Subclass must implement 'checked_merge(e1,e2)'" 196 end
Returns the type used to validate the options hash
@return [Types::PAnyType] the puppet type
# File lib/puppet/pops/merge_strategy.rb 190 def value_t 191 raise NotImplementedError, "Subclass must implement 'value_t'" 192 end