Skip to content

Instantly share code, notes, and snippets.

@JEG2
Forked from thirtysixthspan/DeferrableBlock.rb
Created August 15, 2010 03:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JEG2/525040 to your computer and use it in GitHub Desktop.
Save JEG2/525040 to your computer and use it in GitHub Desktop.
class Context
def initialize(variables)
variables.each do |name, value|
instance_variable_set("@#{name}", value)
end
end
def run(code, start_line)
context = init_context
load_variables(context)
[step_eval(context, code, start_line), read_variables(context)]
end
private
def init_context
binding
end
def load_variables(context)
instance_variables.each do |name, value|
context.eval("#{name[1..-1]} = #{name}")
end
end
def step_eval(context, code, start_line)
lines = code.strip.lines.to_a
start_line.upto(lines.size - 1) do |i|
code_line = lines[i]
puts ">> #{code_line}"
if code_line =~ /\A\s*pause\s*\z/
return i + 1
end
context.eval(code_line)
end
lines.size
end
def read_variables(context)
context.eval("Hash[local_variables.map { |v| [v, eval(v.to_s)] }]")
end
end
class DeferrableBlock
def self.unfreeze(path)
open(path) { |file| Marshal.load(file) }
end
def self.resume(path)
df = self.unfreeze(path)
df.continue
end
def initialize(code, line = 0, variables = { })
@code = code
@line = line
@variables = variables
end
def marshal_dump
[@code, @line, @variables]
end
def marshal_load(code_line_variables)
@code, @line, @variables = code_line_variables
end
def call(variables = { })
@variables.merge!(variables)
execute
end
def continue
execute
end
def freeze(path)
File.open(path, "w") { |file| Marshal.dump(self, file) }
end
private
def execute
@line, @variables = Context.new(@variables).run(@code, @line)
end
end
db = DeferrableBlock.new(<<-END_RUBY)
a = 1
b = 2
puts b
pause
b += c
puts b
END_RUBY
db.call(c: 5)
db.freeze("/tmp/block")
puts "And now for something different"
DeferrableBlock.resume("/tmp/block")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment