MMMultiYield allows your Ruby methods to take multiple named blocks with a simple DSL and yield to them independently in code. This allows for things such as callback and errback blocks, flexible case-like patterns and other stuff I've not thought of.
Ruby 1.9.2 (1.8.7 and Rubinius's implementation of Kernel#caller doesn't show the class if you're called from a class body) JRuby in the future
To define a method within current scope (e.g. within a class):
class Foobar
MMMulti.def :my_new_method do |mmmulti, my_arg|
if my_arg == 'blue'
mmmulti.yield(:callback)
else
mmmulti.yield(:errback)
end
end
end
To define it on an explicit class:
MMMulti.def(String => :my_string_method) do |mmmulti|
if self == 'blue'
mmmulti.yield(:callback)
else
mmmulti.yield(:errback)
end
end
>> Foobar.new.my_new_method 'blue' do
def callback
'omg it r blue'
end
def errback
':((( no blu'
end
end
=> "omg it r blue"
>> 'green'.my_string_method do
def callback
'omg it r blue'
end
def errback
':((( no blu'
end
end
=> ":((( no blu"
If the method tries to yield to a block that isn't named in the block-of-blocks, it will raise NoMethodError
I haven't used BlankSlate for the DSL because HOLY JESUS THAT THING IS SLOW. This is mainly a toy, so perhaps avoid naming your blocks after methods you shouldn't.
Minitest is used for the spec. Enjoy!
Operating on the caller array to determine where to define the method feels wrong to me.