Skip to content

Instantly share code, notes, and snippets.

@iamatypeofwalrus
Created February 18, 2017 04:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save iamatypeofwalrus/bc642f1477121f29be6fde8cd2bee0fa to your computer and use it in GitHub Desktop.
Save iamatypeofwalrus/bc642f1477121f29be6fde8cd2bee0fa to your computer and use it in GitHub Desktop.
Smoke test for using the Kernel#set_trace_func in Ruby 2.x
# Official docs are a _bit_ light on specifcs
# http://ruby-doc.org/core-2.0.0/Kernel.html#method-i-set_trace_func
#
# There are other options if you are interested in a general trace:
# * ruby -r tracer your_script.rb
# * https://ruby-doc.org/core-2.3.0/TracePoint.html
#
# What I'd like to be able to do is create a helper module / class that can be added to any class like so:
#
# class Foo
# include MethodTracerHelper # could be included in test environments only by reopening the class!
#
# def super_cool
# # doing interesting things
# end
# end
#
# Foo.trace(:super_cool) # if no method is given then emit a stack trace for any invocation of any method on the class
#
# MethodTracer.do
# # Do something else that will eventually call in to the Foo#super_cool method
# end
#
# MethodTracer.do will output all stack traces for each invocation of :super_cool into a tmp directory
# like:
# rails-root/tmp/method_tracer/2017-02-17-20:00:15/foo/super_cool/1/
# with files like:
# stacktrace.txt
# arguments.txt
class Foo
def self.foo1()
return "foo1"
end
def foo2(name, age)
return "#{name} is #{age} years old"
end
end
# emit a stack trace when the method :foo2 is called on Foo
Kernel.set_trace_func proc { |event, file, line, id, binding, klass|
next unless klass == Foo && id == :foo2 && event == "call"
puts "stacktrace: #{caller.join("\n")}"
params = klass.instance_method(id).parameters.map {|_, name| name}
vals = {}
params.each do |name|
vals[name] = binding.local_variable_get(name)
end
puts
puts "arguments: #{vals}"
}
def foo_you_man
Foo.new.foo2("Joe", 30)
end
def do_something_else
foo_you_man
end
def do_something
do_something_else
end
do_something
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment