Skip to content

Instantly share code, notes, and snippets.

@Keoven

Keoven/README.md Secret

Created October 15, 2011 05:54
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 Keoven/ced57efe7d74f43b2df6 to your computer and use it in GitHub Desktop.
Save Keoven/ced57efe7d74f43b2df6 to your computer and use it in GitHub Desktop.
Code Brawl Entry: Methods taking multiple blocks

Simple Instance Callback Hash

This is an entry to Code Brawl: Methods taking multiple blocks

The basic idea here is to have your callbacks setup through a method call and not sent as an argument to the method. You can then have these callbacks adapt depending on the other parameters sent through the method. After the method had been executed, it is deleted from the hash.

Example Usage:

class Test
  def setup_callbacks
    callback.hello do |string|
      puts string
    end
  end

  def request
    setup_callbacks
    callback.hello('Hello World')
  end
end
Test.new.request
require 'delegate'
class CallbackHash < DelegateClass(Hash)
def initialize
super(Hash.new)
end
def method_missing(
method_name, *arguments, &block)
if self[method_name].nil?
self[method_name] = block
else
self[method_name].call(*arguments)
self.delete(method_name)
end
end
end
module Kernel
def callback
@cb ||= CallbackHash.new
end
end
@rogerbraun
Copy link

Why delete the method?

@JEG2
Copy link

JEG2 commented Oct 17, 2011

This is a fine approach, but it's more per object than per method.

@jeremyevans
Copy link

I think this example misses the point, as it doesn't allow you to provide a method with multiple blocks.

@Keoven
Copy link
Author

Keoven commented Oct 17, 2011

@JEG2
yep it is per object mostly making the callback available to the whole object to execute* -- That's why the name ;)

@rogerbraun
Because you might have other methods using the same key to call a block
(since if the key exists, it would simply return the block and not assign a new one)
but it would be best to have it different to avoid executing the wrong code*

@jeremyevans
hmmm, it actually depends, I wanted to try not passing anything at all and I was coming from the idea that the end goal was simply to be able to call your callbacks in your method. Which in turn is the reason for passing multiple blocks to the method -- which I tried to eliminate. ;)

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