Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@stephenprater
Last active February 20, 2022 19:59
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save stephenprater/ca312d24578455f36550 to your computer and use it in GitHub Desktop.
Save stephenprater/ca312d24578455f36550 to your computer and use it in GitHub Desktop.
callcc Dream Baby
require 'continuation'
require 'pry'
require 'pry-rescue'
require 'byebug'
require 'pry-stack_explorer'
require 'singleton'
module ContinuationStack
extend self
module Continuable
attr_accessor :name, :my_binding
def initialize(name, my_binding)
self.name = name
self.my_binding = my_binding
Byebug.run_init_script(StringIO.new)
end
def continue
@continuing = true
@continuation.call
end
def remember
callcc { |cc| @continuation = cc }
if @continuing
Byebug.start
Byebug.current_context.step_out(1)
Pry.start_with_pry_byebug(my_binding)
end
ensure
@continuing = false
end
end
def methods
@methods ||= Array(Method.new("(top)", TOPLEVEL_BINDING))
end
def method
methods.last
end
def line
methods.last.lines.last
end
def set!
last.remember
end
def last
if method.begun?
method.line
else
method
end
end
class Method
include Continuable
def continue
# this should be the line that called my method
super
end
def lines
@lines ||= []
end
def line
lines.last
end
def begun?
lines.size > 0
end
end
class Line
include Continuable
attr_reader :path
def initialize(lineno, path, binding)
super(lineno, binding)
@path = path
end
def continue
super
end
end
end
$continuation_stack = {}
disable_trace = false
$trace = TracePoint.new(:call, :line, :return) do |tp|
if tp.event == :call && tp.method_id == :pry
disable_trace = true
elsif tp.event == :return && tp.method_id == :pry
disable_trace = false
next
end
next if disable_trace
case tp.event
when :call
ContinuationStack.methods << ContinuationStack::Method.new(tp.method_id, tp.binding.freeze)
ContinuationStack.set!
when :line
ContinuationStack.method.lines << ContinuationStack::Line.new(tp.lineno, tp.path, tp.binding.freeze)
ContinuationStack.set!
when :return
ContinuationStack.methods.pop
ContinuationStack.set!
end
end
$trace.enable
class Thing
def foo
a ||= 1
puts a += 1
puts a += 1
puts a += 1
binding.pry
end
end
Thing.new.foo
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment