A CallSiteAnalyzer can be used to obtain information about:
where a method is defined ("defsite
")
where a method was called from ("callsite
")
example.rb
:
class X def f1; f2 end def f2; 1 + 1 end def f3; f1 end end analyzer = Rcov::CallSiteAnalyzer.new x = X.new analyzer.run_hooked do x.f1 end # .... analyzer.run_hooked do x.f3 # the information generated in this run is aggregated # to the previously recorded one end analyzer.analyzed_classes # => ["X", ... ] analyzer.methods_for_class("X") # => ["f1", "f2", "f3"] analyzer.defsite("X#f1") # => DefSite object analyzer.callsites("X#f2") # => hash with CallSite => count # associations defsite = analyzer.defsite("X#f1") defsite.file # => "example.rb" defsite.line # => 2
You can have several CallSiteAnalyzer objects at a time, and it is possible to nest the run_hooked / install_hook/remove_hook blocks: each analyzer will manage its data separately. Note however that no special provision is taken to ignore code executed "inside" the CallSiteAnalyzer class.
defsite
information is only available for methods that were
called under the inspection of the CallSiteAnalyzer, i.o.w. you will only
have defsite
information for those methods for which callsite
information is available.
# File lib/rcov/call_site_analyzer.rb, line 101 def initialize super(:install_callsite_hook, :remove_callsite_hook, :reset_callsite) end
Classes whose methods have been called. Returns an array of strings describing the classes (just klass.to_s for each of them). Singleton classes are rendered as:
#<Class:MyNamespace::MyClass>
# File lib/rcov/call_site_analyzer.rb, line 110 def analyzed_classes raw_data_relative.first.keys.map{|klass, meth| klass}.uniq.sort end
Returns a hash with CallSite => call count
associations or
nil
Can be called in two ways:
analyzer.callsites("Foo#f1") # instance method analyzer.callsites("Foo.g1") # singleton method of the class
or
analyzer.callsites("Foo", "f1") analyzer.callsites("#<class:Foo>", "g1")
# File lib/rcov/call_site_analyzer.rb, line 130 def callsites(classname_or_fullname, methodname = nil) rawsites = raw_data_relative.first[expand_name(classname_or_fullname, methodname)] return nil unless rawsites ret = {} # could be a job for inject but it's slow and I don't mind the extra loc rawsites.each_pair do |backtrace, count| ret[CallSite.new(backtrace)] = count end ret end
Returns a DefSite object corresponding to the given method Can be called in two ways:
analyzer.defsite("Foo#f1") # instance method analyzer.defsite("Foo.g1") # singleton method of the class
or
analyzer.defsite("Foo", "f1") analyzer.defsite("#<class:Foo>", "g1")
# File lib/rcov/call_site_analyzer.rb, line 148 def defsite(classname_or_fullname, methodname = nil) file, line = raw_data_relative[1][expand_name(classname_or_fullname, methodname)] return nil unless file && line DefSite.new(file, line) end
Methods that were called for the given class. See analyzed_classes
for the notation used for singleton classes. Returns an array of strings or
nil
# File lib/rcov/call_site_analyzer.rb, line 117 def methods_for_class(classname) a = raw_data_relative.first.keys.select{|kl,_| kl == classname}.map{|_,meth| meth}.sort a.empty? ? nil : a end