Skip to content

Instantly share code, notes, and snippets.

@JesseBuesking
Created January 31, 2017 21:32
Show Gist options
  • Save JesseBuesking/a791fb61dbd7f06307db4f4fd2dccf2e to your computer and use it in GitHub Desktop.
Save JesseBuesking/a791fb61dbd7f06307db4f4fd2dccf2e to your computer and use it in GitHub Desktop.
A method to trace variable changes in your project. Set `__trace_if__` to return true to print *every* line, or have it print conditionally. In the example below I print only when the variable `boof` changes.
lambda do
trace_default_frame = lambda do
{ locals: {} }
end
trace_stack = [trace_default_frame[]]
set_trace_func proc { |event, file, line, id, binding, classname|
if event == 'call' || event == 'c-call'
trace_stack << trace_default_frame[]
elsif event == 'return' || event == 'c-return'
trace_stack.pop
trace_stack << trace_default_frame[] if trace_stack.empty?
end
binding.eval('local_variables').each do |variable_sym|
# don't include local variables used within this lambda
next if [:trace_default_frame, :trace_stack].include?(variable_sym)
old = trace_stack.last[:locals][variable_sym]
new = binding.eval(variable_sym.to_s)
begin
original = new.dup
binding.eval("lambda { |v| #{variable_sym} = v}")[new.dup]
rescue
original = new
end
trace_stack.last[:locals][variable_sym] = original
unless old.nil? || old == new
#binding.eval("lambda { |v| #{variable_sym} = v }")[old]
if Kernel.__trace_if__(event, file, line, id, binding, classname, variable_sym)
printf "%s:%-2d %s changed from '%s' to '%s'\n", file, line, variable_sym, old, new
end
end
end
}
end.call
module Kernel
class << self
def __trace_if__(event, file, line, id, binding, classname, variable_sym)
variable_sym == :boof
end
end
end
boof = 1
10.times do |i|
boof += 1
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment