-
-
Save stephenprater/ca312d24578455f36550 to your computer and use it in GitHub Desktop.
callcc Dream Baby
This file contains 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
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