here is my latest `update' to the idea:

--- code ---
class Proc
  alias __proc_block_call call
  alias __proc_block_indexer []

  @@blocks = []
  
  def Proc.yield(*args)
    fail "No current proc context"          if @@blocks.empty?
    raise LocalJumpError, "no block given"  if @@blocks[-1].nil?
    # Maybe just @block.call? - This allows for recursion, though
    @@blocks[-1].__proc_block_call(*args)
  end

  def Proc.block_given?(*args)
    fail "No current proc context"          if @@blocks.empty?
    !@@blocks[-1].nil?
  end

  def yield(*args)
    Proc.yield(*args)
  end

  def block_given?
    Proc.block_given?
  end

  def call(*args, &block)
    @@blocks.push block
    r = __proc_block_call(*args)
    @@blocks.pop
    r
  end

  def [](*args, &block)
    @@blocks.push block
    r = __proc_block_indexer(*args)
    @@blocks.pop
    r
  end
end


module Kernel
  def pyield(*args)
    Proc.yield(*args)
  end

  def pblock_given?
    Proc.block_given?
  end
end
--- code ---

I still don't know why I can't use a block with the normal use of
[]... is that going to ever change?

I know I can do obj.send(:[], *args) or obj.[](*args) -- but I think
we all know using obj[*args] is best!  :-)

~Me!

-- 
There's no word in the English language for what you do to a dead
thing to make it stop chasing you.