class Puppet::Pops::Types::RecursionGuard

Keeps track of self recursion of conceptual 'this' and 'that' instances using two separate maps and a state. The class is used when tracking self recursion in two objects ('this' and 'that') simultaneously. A typical example of when this is needed is when testing if 'that' Puppet Type is assignable to 'this' Puppet Type since both types may contain self references.

All comparisons are made using the `object_id` of the instance rather than the instance itself.

@api private

Constants

NO_SELF_RECURSION
SELF_RECURSION_IN_BOTH
SELF_RECURSION_IN_THAT
SELF_RECURSION_IN_THIS

Attributes

state[R]

Public Class Methods

new() click to toggle source
   # File lib/puppet/pops/types/recursion_guard.rb
19 def initialize
20   @state = NO_SELF_RECURSION
21 end

Public Instance Methods

add_that(instance) click to toggle source

Add the given argument as 'that' and return the resulting state @param instance [Object] the instance to add @return [Integer] the resulting state

   # File lib/puppet/pops/types/recursion_guard.rb
90 def add_that(instance)
91   if (@state & SELF_RECURSION_IN_THAT) == 0
92     @state = @state | SELF_RECURSION_IN_THAT if that_put(instance)
93   end
94   @state
95 end
add_this(instance) click to toggle source

Add the given argument as 'this' and return the resulting state @param instance [Object] the instance to add @return [Integer] the resulting state

   # File lib/puppet/pops/types/recursion_guard.rb
80 def add_this(instance)
81   if (@state & SELF_RECURSION_IN_THIS) == 0
82     @state = @state | SELF_RECURSION_IN_THIS if this_put(instance)
83   end
84   @state
85 end
recursive_that?(instance) click to toggle source

Checks if recursion was detected for the given argument in the 'that' context @param instance [Object] the instance to check @return [Integer] the resulting state

   # File lib/puppet/pops/types/recursion_guard.rb
33 def recursive_that?(instance)
34   instance_variable_defined?(:@recursive_that_map) && @recursive_that_map.has_key?(instance.object_id)
35 end
recursive_this?(instance) click to toggle source

Checks if recursion was detected for the given argument in the 'this' context @param instance [Object] the instance to check @return [Integer] the resulting state

   # File lib/puppet/pops/types/recursion_guard.rb
26 def recursive_this?(instance)
27   instance_variable_defined?(:@recursive_this_map) && @recursive_this_map.has_key?(instance.object_id)
28 end
that_count() click to toggle source

@return the number of objects added to the `that` map

    # File lib/puppet/pops/types/recursion_guard.rb
103 def that_count
104   instance_variable_defined?(:@that_map) ? @that_map.size : 0
105 end
this_count() click to toggle source

@return the number of objects added to the `this` map

    # File lib/puppet/pops/types/recursion_guard.rb
 98 def this_count
 99   instance_variable_defined?(:@this_map) ? @this_map.size : 0
100 end
with_that(instance) { |state| ... } click to toggle source

Add the given argument as 'that' invoke the given block with the resulting state @param instance [Object] the instance to add @return [Object] the result of yielding

   # File lib/puppet/pops/types/recursion_guard.rb
60 def with_that(instance)
61   if (@state & SELF_RECURSION_IN_THAT) == 0
62     tc = that_count
63     @state = @state | SELF_RECURSION_IN_THAT if that_put(instance)
64     if tc < that_count
65       # recursive state detected
66       result = yield(@state)
67 
68       # pop state
69       @state &= ~SELF_RECURSION_IN_THAT
70       @that_map.delete(instance.object_id)
71       return result
72     end
73   end
74   yield(@state)
75 end
with_this(instance) { |state| ... } click to toggle source

Add the given argument as 'this' invoke the given block with the resulting state @param instance [Object] the instance to add @return [Object] the result of yielding

   # File lib/puppet/pops/types/recursion_guard.rb
40 def with_this(instance)
41   if (@state & SELF_RECURSION_IN_THIS) == 0
42     tc = this_count
43     @state = @state | SELF_RECURSION_IN_THIS if this_put(instance)
44     if tc < this_count
45       # recursive state detected
46       result = yield(@state)
47 
48       # pop state
49       @state &= ~SELF_RECURSION_IN_THIS
50       @this_map.delete(instance.object_id)
51       return result
52     end
53   end
54   yield(@state)
55 end

Private Instance Methods

that_put(o) click to toggle source
    # File lib/puppet/pops/types/recursion_guard.rb
122 def that_put(o)
123   id = o.object_id
124   @that_map ||= {}
125   if @that_map.has_key?(id)
126     @recursive_that_map ||= {}
127     @recursive_that_map[id] = true
128     true
129   else
130     @that_map[id] = true
131     false
132   end
133 end
this_put(o) click to toggle source
    # File lib/puppet/pops/types/recursion_guard.rb
109 def this_put(o)
110   id = o.object_id
111   @this_map ||= {}
112   if @this_map.has_key?(id)
113     @recursive_this_map ||= {}
114     @recursive_this_map[id] = true
115     true
116   else
117     @this_map[id] = true
118     false
119   end
120 end