Guest User

Untitled

a guest
May 24th, 2018
96
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 0.91 KB | None | 0 0
  1. def Binding.of_caller(&block)
  2. old_critical, Thread.critical = Thread.critical, true
  3. count = 0
  4. cc = nil
  5. result, error = callcc{|c|cc=c}
  6. error.call if error
  7.  
  8. tracer = lambda do |*args|
  9. type, _, _, _, context = args
  10. if ["return", "c-return"].include?(type)
  11. count += 1
  12. # First this method and then calling one will return -- the trace event of the second event gets the context
  13. # of the method which called the method that called method.
  14. if count == 2
  15. set_trace_func(nil)
  16. cc.call(eval("binding", context), nil)
  17. end
  18. elsif type != "line"
  19. set_trace_func(nil)
  20. cc.call(nil, lambda { raise(Exception, "Binding.of_caller used in non-method context or trailing statements of method using it aren't in the block." ) })
  21. end
  22. end
  23.  
  24. if result
  25. Thread.critical = old_critical
  26. yield result
  27. else
  28. set_trace_func(tracer)
  29. return nil
  30. end
  31. end
Add Comment
Please, Sign In to add comment