Skip to content

Instantly share code, notes, and snippets.

@thirtysixthspan
Created August 14, 2010 21:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save thirtysixthspan/524746 to your computer and use it in GitHub Desktop.
Save thirtysixthspan/524746 to your computer and use it in GitHub Desktop.
class DeferrableBlock
attr_reader :deferred
attr_reader :binding
def initialize(block, binding=nil)
@code = block
@binding = binding || Kernel.binding
@deferred = false
end
def self._load(block)
binding = Kernel.binding
code, variables = Marshal.load(block)
variables.each do |var,val|
next if var == 'block' || var == 'binding'
binding.eval("#{var}=Marshal.load(#{val.inspect})")
end
new(code,binding)
end
def _dump( depth )
@binding.eval('variables = Hash.new')
@binding.eval('local_variables.each { |sym| variables[sym.to_s]=Marshal.dump(eval(sym.to_s)) if sym!=:variables}')
a = [ @code, @binding.eval('variables') ]
s = Marshal.dump(a)
end
def step_eval(code, start_line=0)
@deferred = false
code.each_index do |i|
next if i < start_line
puts ">>"+@code[i]
if @code[i]=="pause"
@binding.eval("line = #{i+1}")
@deferred=true
break
end
@binding.eval @code[i]
end
end
def call(params={})
params.each {|param,val| @binding.eval("#{param} = #{val}") }
step_eval @code
end
def continue
step_eval(@code, @binding.eval('line'))
end
def freeze(name)
File.open(name, "w") { |file| Marshal.dump(self, file) }
end
def self.unfreeze(name)
File.open(name) { |file| Marshal.load(file) }
end
def self.resume(name)
block = self.unfreeze(name)
block.continue
end
end
code = Array.new([
"a = 1",
"b = 2",
"puts b",
"pause",
"b += c",
"puts b"
]);
block = DeferrableBlock.new(code)
block.call( {'c'=>5 } )
block.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