Class: Emf::Visitors::Stats

Inherits:
Model::Visitor show all
Defined in:
lib/emf/visitors/stats.rb

Overview

Produces a record-class histogram for a Metafile. Used by spec assertions (TODO 16) and as a quick sanity-check dump via emf stats (TODO 19).

The base Visitor auto-registers visit_* methods as no-ops. Stats overrides the generic dispatch to tally every record by its class name. Subclasses that override specific visit_* methods for richer behaviour still get tallied here because the record's accept calls the visit_* method, which (if not overridden) calls method_missing -> tally.

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods inherited from Model::Visitor

register_visit, visit_all

Constructor Details

#initializeStats

Returns a new instance of Stats.



14
15
16
# File 'lib/emf/visitors/stats.rb', line 14

def initialize
  @counts = Hash.new(0)
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(name, *args) ⇒ Object



51
52
53
54
55
56
# File 'lib/emf/visitors/stats.rb', line 51

def method_missing(name, *args)
  return super unless name.to_s.start_with?("visit_")

  record = args.first
  @counts[record.class.name&.split("::")&.last || record.class.to_s] += 1 if record
end

Instance Attribute Details

#countsObject (readonly)

Returns the value of attribute counts.



18
19
20
# File 'lib/emf/visitors/stats.rb', line 18

def counts
  @counts
end

Instance Method Details

#histogramObject



20
21
22
# File 'lib/emf/visitors/stats.rb', line 20

def histogram
  @counts.sort.to_h
end

#respond_to_missing?(name, _include_private = false) ⇒ Boolean

Returns:

  • (Boolean)


58
59
60
# File 'lib/emf/visitors/stats.rb', line 58

def respond_to_missing?(name, _include_private = false)
  name.to_s.start_with?("visit_") || super
end

#to_sObject



28
29
30
31
32
# File 'lib/emf/visitors/stats.rb', line 28

def to_s
  lines = ["Total: #{total}", ""]
  histogram.each { |klass, count| lines << format("%6d  %s", count, klass) }
  lines.join("\n")
end

#totalObject



24
25
26
# File 'lib/emf/visitors/stats.rb', line 24

def total
  @counts.values.sum
end

#visit(record) ⇒ Object



34
35
36
37
# File 'lib/emf/visitors/stats.rb', line 34

def visit(record)
  record.accept(self)
  self
end

#visit_all(metafile) ⇒ Object



39
40
41
42
# File 'lib/emf/visitors/stats.rb', line 39

def visit_all(metafile)
  metafile.each { |record| record.accept(self) }
  self
end

#visit_emr_wire_record(adapter) ⇒ Object

WireAdapter is the catch-all for unknown record types. Tally by the underlying wire class so the histogram is informative.



46
47
48
49
# File 'lib/emf/visitors/stats.rb', line 46

def visit_emr_wire_record(adapter)
  wire_class = adapter.wire.class.name&.split("::")&.last || "Raw"
  @counts["WireAdapter(#{wire_class})"] += 1
end