Created
February 18, 2017 04:51
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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