Module: MethodAnalyzer

Defined in:
lib/method_analyzer.rb

Constant Summary collapse

@@methods =
Hash.new{ |h,k| h[k] = Hash.new{ |h,k| h[k] = []} }
@@whereis =
[]
@@expand_path =
Hash.new{ |h,k| h[k] = File.expand_path(k)}

Class Method Summary collapse

Class Method Details

.at_exit__output_marshalObject



58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/method_analyzer.rb', line 58

def self.at_exit__output_marshal
  at_exit do
    set_trace_func nil
    dbfile = "method_analysis"
    old = Marshal.load(File.read(dbfile)) rescue {}
    open(dbfile, "wb") do |io|
      # Because Marshal.dump cannot handle hashes with default_proc
      @@methods.default = nil
      @@methods.each_value{ |v| v.default=nil; v.each_value{ |vv| vv.uniq! } }
      Marshal.dump(@@methods.merge(old), io)
    end
  end
end

.at_exit__output_textObject



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/method_analyzer.rb', line 73

def self.at_exit__output_text
  at_exit do
    set_trace_func nil
    puts "method fullnames"
    @@methods.sort.each do |file, lines|
      lines.sort.each do |line, methods|
        printf "%s:%s:%s\n", file, line, methods.uniq.join(" ")
      end
    end

    puts
    puts "method definitions"
    @@whereis.sort.uniq.each do |file, line, fullname |
      printf "%s:%s:%s\n", file, line, fullname
    end

  end
end

.set_at_exitObject



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

def self.set_at_exit
  case ENV['METHOD_ANALYZER_FORMAT']
  when 'marshal'
    at_exit__output_marshal
  else
    at_exit__output_text
  end
end

.trace_func(event, file, line, id, binding, klass, *rest) ⇒ Object



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/method_analyzer.rb', line 32

def self.trace_func(event, file, line, id, binding, klass, *rest)
  return if file == __FILE__
  return if (event != 'call' and event != 'c-call')
  return if klass == Class and id == :inherited
  return if klass == Module and id == :method_added
  return if klass == Kernel and id == :singleton_method_added
  saved_crit = Thread.critical
  Thread.critical = true
  
  the_self = eval("self",binding)
  flag = Class === the_self ? "." : "#"
  #klass = klass == Kernel ? Object : klass
  fullname = "#{klass}#{flag}#{id}"
  file.replace @@expand_path[file]
  if event == 'call'
    @@whereis << [file, line, fullname] if file !~ /\(eval\)$/
    file, line, rest = caller(4)[0].split(/:/)
    file.replace @@expand_path[file] # DRY
    p caller(0) if $DEBUG
    line = line.to_i
  end
  @@methods[file][line] << fullname  if event =~ /call/

  Thread.critical = saved_crit
end