Module: SuperDiff::Core::RecursionGuard

Defined in:
lib/super_diff/core/recursion_guard.rb

Constant Summary collapse

RECURSION_GUARD_KEY =
'super_diff_recursion_guard_key'
PLACEHOLDER =
'∙∙∙'

Class Method Summary collapse

Class Method Details

.already_seen?(object) ⇒ Boolean

Returns:

  • (Boolean)


45
46
47
# File 'lib/super_diff/core/recursion_guard.rb', line 45

def self.already_seen?(object)
  already_seen_object_ids.include?(object.object_id)
end

.already_seen_object_idsObject



49
50
51
# File 'lib/super_diff/core/recursion_guard.rb', line 49

def self.already_seen_object_ids
  Thread.current[RECURSION_GUARD_KEY] ||= Set.new
end

.guarding_recursion_of(*objects, &block) ⇒ Object



11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/super_diff/core/recursion_guard.rb', line 11

def self.guarding_recursion_of(*objects, &block)
  already_seen_objects, first_seen_objects =
    objects.partition do |object|
      !SuperDiff.primitive?(object) && already_seen?(object)
    end

  first_seen_objects.each do |object|
    already_seen_object_ids.add(object.object_id)
  end

  result =
    if block.arity.positive?
      block.call(already_seen_objects.any?)
    else
      block.call
    end

  first_seen_objects.each do |object|
    already_seen_object_ids.delete(object.object_id)
  end

  result
end

.substituting_recursion_of(*objects) ⇒ Object



35
36
37
38
39
40
41
42
43
# File 'lib/super_diff/core/recursion_guard.rb', line 35

def self.substituting_recursion_of(*objects)
  guarding_recursion_of(*objects) do |already_seen|
    if already_seen
      PLACEHOLDER
    else
      yield
    end
  end
end