原です。

また思いつきを書きますが、自分自身を表す Proc オブジェクト
というのを Proc.current で返すようにしたらどうでしょう。
Thread のまねです。すると、n! は次の様に書けるわけです:

   factorize = Proc.new{ |n|
     n.zero? ? 1 : Proc.current.call(n-1) * n
   }


さらに、ブロックローカル変数についての提案ですが、まず
Proc#[] を廃止(この時点でこの提案は却下確定?)、改め
てProc#[], Proc#[]= をブロックローカル変数の参照、代入
に用いる:

   def foo; yield 1; end
   foo {
     Proc.current[:x] = 0
     foo {|Proc.current[:x]|
       p Proc.current[:x] #=> 1
       Proc.current[:x] = 2
     }
     p Proc.current[:x] #=> 0
   }


もう一つ提案。Proc#[] はまずいから、Proc.[], Proc.[]= にしてしまっ
たらどうか:

   def foo; yield 1; end
   foo {
     Proc[:x] = 0
     foo {|Proc[:x]|
       p Proc[:x] #=> 1
       Proc[:x] = 2
     }
     p Proc[:x] #=> 0
   }

もはや "Proc" である必要はないですが。
こうすると完全に外部、内部と隔離されます。