Skip to content

Instantly share code, notes, and snippets.

@Heimdell
Last active October 18, 2017 21:32
Show Gist options
  • Select an option

  • Save Heimdell/699e525e18f0058f4d6189e778dc9d63 to your computer and use it in GitHub Desktop.

Select an option

Save Heimdell/699e525e18f0058f4d6189e778dc9d63 to your computer and use it in GitHub Desktop.
"""
I want to store some call tree, like
> push 1
> seq do
> dup
> push 1
> drop
> end
> swap
... and then unleash it on some object.
Notice, that call results are ignored,
since in the end I'm only interested in side-effects.
"""
"""
This object stores any call tree invoked on it.
"""
class Catcher
def initialize
@context = [[]]
end
def method_missing name, *args
if block_given? then
@context.push []
yield
chain = @context.pop
@context.last.push name: name, args: args, do: chain
else
@context.last.push name: name, args: args
end
end
end
"""
This method will invoke some call tree on the Catcher
and return what got stored.
"""
def callTree &block
catcher = Catcher.new
catcher.instance_eval &block
catcher.instance_eval do
@context.last
end
end
"""
This method will replay call tree on the object it is invoked on.
"""
def callTheTree tree
this = self
tree.each do |node|
this.instance_eval do
if node[:do] then
this.send node[:name], node[:args] do
callTheTree node[:do]
end
else
this.send node[:name], node[:args]
end
end
end
end
"""
This is a test object that just yells any message sent to it into the console.
"""
class Yeller
def method_missing name, args, &block
# TODO: replace HAX with proper thingies
# NOTICE: begin super.[name](args, &block); rescue e; ...; end
# doesn't work, it just hangs in a loop
return super.send name, args, &block if name == :callTheTree
@indent ||= 0
put "#{name}(#{args.join ", "})"
if block_given? then
put "{"
@indent += 1
yield
@indent -= 1
put "}"
end
end
def put thing
puts (" " * @indent + thing.to_s)
end
end
# dig the tree out
tree = callTree do
seq do
dup
push 1
par do
seq do
dup
drop
end
drop
end
end
end
# plant the tree to the yelling land
Yeller.new.instance_eval do
callTheTree tree
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment