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
20 def initialize
21   @state = NO_SELF_RECURSION
22 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
91 def add_that(instance)
92   if (@state & SELF_RECURSION_IN_THAT) == 0
93     @state = @state | SELF_RECURSION_IN_THAT if that_put(instance)
94   end
95   @state
96 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
81 def add_this(instance)
82   if (@state & SELF_RECURSION_IN_THIS) == 0
83     @state = @state | SELF_RECURSION_IN_THIS if this_put(instance)
84   end
85   @state
86 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
34 def recursive_that?(instance)
35   instance_variable_defined?(:@recursive_that_map) && @recursive_that_map.has_key?(instance.object_id)
36 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
27 def recursive_this?(instance)
28   instance_variable_defined?(:@recursive_this_map) && @recursive_this_map.has_key?(instance.object_id)
29 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
104 def that_count
105   instance_variable_defined?(:@that_map) ? @that_map.size : 0
106 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
 99 def this_count
100   instance_variable_defined?(:@this_map) ? @this_map.size : 0
101 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
61 def with_that(instance)
62   if (@state & SELF_RECURSION_IN_THAT) == 0
63     tc = that_count
64     @state = @state | SELF_RECURSION_IN_THAT if that_put(instance)
65     if tc < that_count
66       # recursive state detected
67       result = yield(@state)
68 
69       # pop state
70       @state &= ~SELF_RECURSION_IN_THAT
71       @that_map.delete(instance.object_id)
72       return result
73     end
74   end
75   yield(@state)
76 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
41 def with_this(instance)
42   if (@state & SELF_RECURSION_IN_THIS) == 0
43     tc = this_count
44     @state = @state | SELF_RECURSION_IN_THIS if this_put(instance)
45     if tc < this_count
46       # recursive state detected
47       result = yield(@state)
48 
49       # pop state
50       @state &= ~SELF_RECURSION_IN_THIS
51       @this_map.delete(instance.object_id)
52       return result
53     end
54   end
55   yield(@state)
56 end

Private Instance Methods

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