Module: SuperDiff::RecursionGuard

Defined in:
lib/super_diff/recursion_guard.rb

Constant Summary collapse

RECURSION_GUARD_KEY =
"super_diff_recursion_guard_key".freeze
PLACEHOLDER =
"∙∙∙".freeze

Class Method Summary collapse

Class Method Details

.already_seen?(object) ⇒ Boolean

Returns:

  • (Boolean)


42
43
44
# File 'lib/super_diff/recursion_guard.rb', line 42

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

.already_seen_object_idsObject



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

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

.guarding_recursion_of(*objects, &block) ⇒ Object



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

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 > 0
      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



32
33
34
35
36
37
38
39
40
# File 'lib/super_diff/recursion_guard.rb', line 32

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