= MultiBlock

MultiBlock is a mini framework for passing multiple blocks to methods. It uses "named procs" to accomplish this in a nice way. The receiving method can either yield all blocks, or just call specific ones, identified by order or name.

These gem was build during a codebrawl contest. You might also take a look at the other entries: http://codebrawl.com/contests/methods-taking-multiple-blocks

== Setup

    gem install multi_block

== Named Procs
A named proc acts like a normal proc, but has got a name attribute. You can create it by calling a method with the desired name on +proc+:

    >> a = proc.even?{ |e| e.even? }
    => #<NamedProc:0x00000001ffc340@(irb):1>
    >> a.name
    => :even?
    >> a[42]
    => false

In the same way, you can create lambdas:

    >> b = lambda.doubler{ |e| e * 2 }
    => #<NamedProc:0x000000020685e0@(irb):7 (lambda)>
    >> b.name
    => :doubler
    >> b[21]
    => 42
    >> b.lambda?
    => true

== MultiBlock Usage
=== Defining methods that use multiple blocks

The first argument given to yield always defines the desired block(s). The other arguments get directly passed to the block(s). So these are example calls to the block:

    yield                                            # calls all given procs without args
    yield :success                                   # calls :success proc without args
    yield :success, "Code Brawl!"                    # calls :success proc with message
    yield 1                                          # calls first proc (:success in this case)
    yield [:success, :bonus]                         # calls :success and :bonus without args
    yield [:success, :bonus], "Code Brawl!"          # calls both procs with same arg
    yield success: "Code Brawl!",                    # calls each keyed proc,
          error:   [500, "Internal Brawl Error"]     #       values are the args

Consider these two example methods:

    def ajax
      yield rand(6) != 0 ? :success : :error # calls the :success block if everything worked well
    end

    def dice
      random_number = rand(6)
      yield random_number, random_number + 1 # calls the n-th block
    end

=== Calling methods with multiple blocks

It's done by calling the +blocks+ helper method:

    ajax &blocks[
      proc.success do puts "Yeah!" end,
      proc.error   do puts "Error..." end,
    ]

The dice method could, for example, be called in this way:

    dice &blocks[
      proc{ ":(" },
      proc{ ":/" },
      proc{ ":O" },
      proc{ ":b" },
      proc{ ":P" },
      proc{ rand(42) != 0 ? ":)"  : ":D"},
    ]

== Bonus sugar: Array extension

If you like the slim <tt>&to_proc</tt> operator, you can further optimize the syntax by calling:

    Array.send :include, MultiBlock::Array

Now, it's getting real hot:

    do_something, some_argument, &[
      proc.easy_way do
        # do it the easy way
      end,
      
      proc.complex_way do
        # use complex heuristics, etc.
      end,
    ]

== J-_-L