Skip to content

Instantly share code, notes, and snippets.

@nilbus
Forked from ryanlecompte/gist:1420133
Last active February 23, 2016 23:35
Show Gist options
  • Save nilbus/6385142 to your computer and use it in GitHub Desktop.
Save nilbus/6385142 to your computer and use it in GitHub Desktop.
Ruby multiple callbacks
# alternative to what is explained in the article Ruby Blocks as Dynamic Callbacks:
# http://www.mattsears.com/articles/2011/11/27/ruby-blocks-as-dynamic-callbacks
class Callbacks
def initialize(block)
block.call(self)
end
def callback(message, *args)
callbacks[message].call(*args)
end
def method_missing(m, *args, &block)
block ? callbacks[m] = block : super
self
end
private
def callbacks
@callbacks ||= {}
end
end
class Twitter
def tweet(msg, &block)
callbacks = Callbacks.new(block)
publish(msg)
callbacks.callback(:success)
rescue => e
callbacks.callback(:failure, e.message)
end
end
t = Twitter.new
t.tweet('Hello there!') do |on|
on.success do
puts "Success!"
end
on.failure do |msg|
puts "Failure! Message: #{msg}"
end
end
@rmontgomery429
Copy link

I like what you've done here. I'm wondering if there a gem of this somewhere or if creating one wouldn't be a bad idea.

@JadedEvan
Copy link

For n00bs like myself who are trying to practice the dark art of Procs, the key component at play is the #method_missing piece. This will register the callback (on.success, on.failure) as a symbolized key in the @callbacks hash, but only once.

A similar solution would be to define methods success and failure on the Twitter class. For those new to experimenting with Procs, this solution may work a little better as the code path is a little more transparent.

Thanks for this tacit and well crafted example!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment