Class: GunDog::TraceStack

Inherits:
Array
  • Object
show all
Defined in:
lib/gun_dog/trace_stack.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(klass) ⇒ TraceStack



19
20
21
22
# File 'lib/gun_dog/trace_stack.rb', line 19

def initialize(klass)
  @klass = klass
  @collaborating_classes = Set.new
end

Instance Attribute Details

#collaborating_classesObject (readonly)

Returns the value of attribute collaborating_classes.



3
4
5
# File 'lib/gun_dog/trace_stack.rb', line 3

def collaborating_classes
  @collaborating_classes
end

#klassObject (readonly)

Returns the value of attribute klass.



3
4
5
# File 'lib/gun_dog/trace_stack.rb', line 3

def klass
  @klass
end

Class Method Details

.from_json(json) ⇒ Object



5
6
7
8
9
10
11
12
13
# File 'lib/gun_dog/trace_stack.rb', line 5

def self.from_json(json)
  ts = new(json['klass'])

  ts.instance_eval do
    @collaborating_classes = Set.new(json['collaborating_classes'].map { |k| Kernel.const_get(k) })
  end

  ts
end

Instance Method Details

#<<(frame) ⇒ Object



52
53
54
55
# File 'lib/gun_dog/trace_stack.rb', line 52

def <<(frame)
  collaborating_classes.add(frame.klass) if preceded_by_traced_klass?
  super(frame)
end

#call_stackObject



47
48
49
50
# File 'lib/gun_dog/trace_stack.rb', line 47

def call_stack
  # the stack excluding the sentinel (element zero) and our selves (element -1)
  self.slice(1 .. -2) || TraceStack.new(klass)
end

#classes_in_stackObject



15
16
17
# File 'lib/gun_dog/trace_stack.rb', line 15

def classes_in_stack
  self.group_by(&:klass).keys.to_set
end

#cyclical_stack?Boolean



31
32
33
34
35
36
# File 'lib/gun_dog/trace_stack.rb', line 31

def cyclical_stack?
  # if the set of classes contained in the trace is a superset of the set
  # of our class then it is a cyclical stack (ie, it contains calls both
  # within and without of the class)
  call_stack.classes_in_stack > self_set
end

#internal_stack?Boolean



24
25
26
27
28
29
# File 'lib/gun_dog/trace_stack.rb', line 24

def internal_stack?
  # if the set of the classes contained in the trace is equivalent to the
  # set of our own class then it is an interal stack (ie - all methods are
  # internal to the traced class)
  call_stack.classes_in_stack == self_set
end

#preceded_by_traced_klass?Boolean



38
39
40
41
# File 'lib/gun_dog/trace_stack.rb', line 38

def preceded_by_traced_klass?
  traced_klasses = self.map(&:klass)
  traced_klasses.include?(klass) || traced_klasses.include?(klass.singleton_class)
end

#self_setObject



43
44
45
# File 'lib/gun_dog/trace_stack.rb', line 43

def self_set
  [klass].to_set
end