Class: Puppet::Pops::Types::RecursionGuard Private

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

Overview

This class is part of a private API. You should avoid using this class if possible, as it may be removed or be changed in the future.

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.

Hash#compare_by_identity is intentionally not used since we only need to keep track of object ids we've seen before, based on object_id, so we don't store entire objects in memory.

Constant Summary collapse

NO_SELF_RECURSION =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

0
SELF_RECURSION_IN_THIS =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

1
SELF_RECURSION_IN_THAT =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

2
SELF_RECURSION_IN_BOTH =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

3

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeRecursionGuard

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns a new instance of RecursionGuard.



25
26
27
# File 'lib/puppet/pops/types/recursion_guard.rb', line 25

def initialize
  @state = NO_SELF_RECURSION
end

Instance Attribute Details

#stateObject (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



18
19
20
# File 'lib/puppet/pops/types/recursion_guard.rb', line 18

def state
  @state
end

Instance Method Details

#add_that(instance) ⇒ Integer

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Add the given argument as 'that' and return the resulting state

Parameters:

  • instance (Object)

    the instance to add

Returns:

  • (Integer)

    the resulting state



96
97
98
99
100
101
# File 'lib/puppet/pops/types/recursion_guard.rb', line 96

def add_that(instance)
  if (@state & SELF_RECURSION_IN_THAT) == 0
    @state |= SELF_RECURSION_IN_THAT if that_put(instance)
  end
  @state
end

#add_this(instance) ⇒ Integer

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Add the given argument as 'this' and return the resulting state

Parameters:

  • instance (Object)

    the instance to add

Returns:

  • (Integer)

    the resulting state



86
87
88
89
90
91
# File 'lib/puppet/pops/types/recursion_guard.rb', line 86

def add_this(instance)
  if (@state & SELF_RECURSION_IN_THIS) == 0
    @state |= SELF_RECURSION_IN_THIS if this_put(instance)
  end
  @state
end

#recursive_that?(instance) ⇒ Integer

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Checks if recursion was detected for the given argument in the 'that' context

Parameters:

  • instance (Object)

    the instance to check

Returns:

  • (Integer)

    the resulting state



39
40
41
# File 'lib/puppet/pops/types/recursion_guard.rb', line 39

def recursive_that?(instance)
  instance_variable_defined?(:@recursive_that_map) && @recursive_that_map.has_key?(instance.object_id) # rubocop:disable Lint/HashCompareByIdentity
end

#recursive_this?(instance) ⇒ Integer

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Checks if recursion was detected for the given argument in the 'this' context

Parameters:

  • instance (Object)

    the instance to check

Returns:

  • (Integer)

    the resulting state



32
33
34
# File 'lib/puppet/pops/types/recursion_guard.rb', line 32

def recursive_this?(instance)
  instance_variable_defined?(:@recursive_this_map) && @recursive_this_map.has_key?(instance.object_id) # rubocop:disable Lint/HashCompareByIdentity
end

#that_countObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns the number of objects added to the that map.

Returns:

  • the number of objects added to the that map



109
110
111
# File 'lib/puppet/pops/types/recursion_guard.rb', line 109

def that_count
  instance_variable_defined?(:@that_map) ? @that_map.size : 0
end

#this_countObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns the number of objects added to the this map.

Returns:

  • the number of objects added to the this map



104
105
106
# File 'lib/puppet/pops/types/recursion_guard.rb', line 104

def this_count
  instance_variable_defined?(:@this_map) ? @this_map.size : 0
end

#with_that(instance) {|@state| ... } ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Add the given argument as 'that' invoke the given block with the resulting state

Parameters:

  • instance (Object)

    the instance to add

Yields:

Returns:

  • (Object)

    the result of yielding



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/puppet/pops/types/recursion_guard.rb', line 66

def with_that(instance)
  if (@state & SELF_RECURSION_IN_THAT) == 0
    tc = that_count
    @state |= SELF_RECURSION_IN_THAT if that_put(instance)
    if tc < that_count
      # recursive state detected
      result = yield(@state)

      # pop state
      @state &= ~SELF_RECURSION_IN_THAT
      @that_map.delete(instance.object_id)
      return result
    end
  end
  yield(@state)
end

#with_this(instance) {|@state| ... } ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Add the given argument as 'this' invoke the given block with the resulting state

Parameters:

  • instance (Object)

    the instance to add

Yields:

Returns:

  • (Object)

    the result of yielding



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/puppet/pops/types/recursion_guard.rb', line 46

def with_this(instance)
  if (@state & SELF_RECURSION_IN_THIS) == 0
    tc = this_count
    @state |= SELF_RECURSION_IN_THIS if this_put(instance)
    if tc < this_count
      # recursive state detected
      result = yield(@state)

      # pop state
      @state &= ~SELF_RECURSION_IN_THIS
      @this_map.delete(instance.object_id)
      return result
    end
  end
  yield(@state)
end