Skip to content

Instantly share code, notes, and snippets.

@creationix
Created December 9, 2009 18:13
Show Gist options
  • Save creationix/252645 to your computer and use it in GitHub Desktop.
Save creationix/252645 to your computer and use it in GitHub Desktop.
simple dispatcher using method_missing in Ruby
class Dispatcher
# Remove the cruft to try to keep the options clear
instance_methods.each { |m| undef_method m unless m =~ /^__|instance_variable_?e?|object_id|inspect|dup/ }
# Store the callback and initialize the route
def initialize(&block)
@route = []
@block = block
end
def chain(name, *args)
@route = @route + [name]
if args.length > 0
@block.call(@route, *args)
end
if block_given?
yield(@route, *args)
end
self
end
# Keep building the route on duped copied of self
def method_missing(*args, &block)
self.dup.chain(*args, &block)
end
end
a = Dispatcher.new do |route, *args|
p "Route #{route.inspect} message #{args.inspect}"
end
log = lambda { |*args| p args }
a.b(:hi).c(:cool).d.e.f :GO, :param2
a.b(1,2,3,&log).c(&log).d{|route|p route}.e.f.g.h.i.j.k.l do |route|
p route
end
# Sample output
#
# "Route [:b] message [:hi]"
# "Route [:b, :c] message [:cool]"
# "Route [:b, :c, :d, :e, :f] message [:GO, :param2]"
# "Route [:b] message [1, 2, 3]"
# [[:b], 1, 2, 3]
# [[:b, :c]]
# [:b, :c, :d]
# [:b, :c, :d, :e, :f, :g, :h, :i, :j, :k, :l]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment