Class: Hometown::DisposalTracer

Inherits:
Object
  • Object
show all
Defined in:
lib/hometown/disposal_tracer.rb

Constant Summary collapse

UNDISPOSED_HEADING =
"Undisposed Resources"
UNTRACED_HEADING =
"Untraced Disposals"
UNDISPOSED_TOTALS_HEADING =
"Undisposed Totals"
UNTRACED_TOTALS_HEADING =
"Untraced Disposals Totals"

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeDisposalTracer

Returns a new instance of DisposalTracer.



5
6
7
8
9
10
# File 'lib/hometown/disposal_tracer.rb', line 5

def initialize
  @tracing_classes = {}

  @undisposed         = Hash.new(0)
  @untraced_disposals = Hash.new(0)
end

Instance Attribute Details

#undisposedObject (readonly)

Returns the value of attribute undisposed.



3
4
5
# File 'lib/hometown/disposal_tracer.rb', line 3

def undisposed
  @undisposed
end

#untraced_disposalsObject (readonly)

Returns the value of attribute untraced_disposals.



3
4
5
# File 'lib/hometown/disposal_tracer.rb', line 3

def untraced_disposals
  @untraced_disposals
end

Instance Method Details

#add_heading_if_needed(heading, result) ⇒ Object



93
94
95
96
97
98
99
# File 'lib/hometown/disposal_tracer.rb', line 93

def add_heading_if_needed(heading, result)
  if result.empty?
    ""
  else
    "#{heading}:\n#{result}"
  end
end

#format_totals(heading, hash) ⇒ Object



81
82
83
84
85
86
87
88
89
90
91
# File 'lib/hometown/disposal_tracer.rb', line 81

def format_totals(heading, hash)
  result = ""
  hash.group_by { |trace, _| trace.traced_class }.each do |clazz, counts|
    count = counts.map { |count| count.last }.inject(0, &:+)
    if count > 0
      result += "[#{clazz}] => #{count}\n"
    end
  end

  add_heading_if_needed(heading, result)
end

#format_trace_hash(heading, hash) ⇒ Object



69
70
71
72
73
74
75
76
77
78
79
# File 'lib/hometown/disposal_tracer.rb', line 69

def format_trace_hash(heading, hash)
  result = ""
  hash.each do |trace, count|
    if count > 0
      result += "[#{trace.traced_class}] => #{count}\n"
      result += "\t#{trace.backtrace.join("\n\t")}\n\n"
    end
  end

  add_heading_if_needed(heading, result)
end

#mark_for_disposal(instance) ⇒ Object



39
40
41
42
# File 'lib/hometown/disposal_tracer.rb', line 39

def mark_for_disposal(instance)
  trace = Hometown.for(instance)
  @undisposed[trace] += 1
end

#notice_disposed(instance) ⇒ Object



44
45
46
47
48
49
50
51
52
# File 'lib/hometown/disposal_tracer.rb', line 44

def notice_disposed(instance)
  trace = Hometown.for(instance)
  if trace
    @undisposed[trace] -= 1
  else
    trace = Trace.new(instance.class, caller)
    @untraced_disposals[trace] += 1
  end
end

#patch(clazz, disposal_method) ⇒ Object



12
13
14
15
16
17
18
# File 'lib/hometown/disposal_tracer.rb', line 12

def patch(clazz, disposal_method)
  return if @tracing_classes.include?(clazz)
  @tracing_classes[clazz] = true

  trace_creation(clazz)
  patch_disposal_method(clazz, disposal_method)
end

#patch_disposal_method(clazz, disposal_method) ⇒ Object



24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/hometown/disposal_tracer.rb', line 24

def patch_disposal_method(clazz, disposal_method)
  traced   = "#{disposal_method}_traced"
  untraced = "#{disposal_method}_untraced"

  clazz.class_eval do
    define_method(traced) do |*args, &blk|
      Hometown.disposal_tracer.notice_disposed(self)
      self.send(untraced, *args, &blk)
    end

    alias_method untraced, disposal_method
    alias_method disposal_method, traced
  end
end

#trace_creation(clazz) ⇒ Object



20
21
22
# File 'lib/hometown/disposal_tracer.rb', line 20

def trace_creation(clazz)
  Hometown.creation_tracer.patch(clazz, method(:mark_for_disposal))
end

#undisposed_reportObject



59
60
61
62
63
64
65
66
67
# File 'lib/hometown/disposal_tracer.rb', line 59

def undisposed_report
  result  = format_trace_hash(UNDISPOSED_HEADING, @undisposed)
  result += format_trace_hash(UNTRACED_HEADING, @untraced_disposals)

  result += format_totals(UNDISPOSED_TOTALS_HEADING, @undisposed)
  result += format_totals(UNTRACED_TOTALS_HEADING, @untraced_disposals)

  result
end