I have found a small 1.8.7 bug that prevents proc_alloc from retrieving the
old Proc object if the Proc has a metaclass. Here's an example:

def foo
  yield
end

def bar(&block)
  puts Proc.new.object_id
  def block.foo() "FOO" end
  puts Proc.new.object_id
  baz(&block)
end

def baz(&block)
  puts Proc.new.object_id
  yield
end

foo { puts "HELLO" }
bar { puts "HELLO" }

Ruby 1.9, Rubinius and JRuby all return the same Proc object in all three
cases. Ruby 1.8.7 returns a different Proc object in each case, because of
the use of CLASS_OF in proc_alloc:

    if (!proc && ruby_block->block_obj && CLASS_OF(ruby_block->block_obj) ==
klass) {
return ruby_block->block_obj;
    }

It seems this code is trying to make sure that MyProc.new doesn't return a
Proc object. The solution is a tiny patch to use rb_class_real:

index 8847ee5..54a0f46 100644
--- a/eval.c
+++ b/eval.c
@@ -8725,7 +8725,7 @@ proc_alloc(klass, proc)
        rb_warn("tried to create Proc object without a block");
     }

-    if (!proc && ruby_block->block_obj && CLASS_OF(ruby_block->block_obj)
== klass) {
+    if (!proc && ruby_block->block_obj &&
rb_class_real(CLASS_OF(ruby_block->block_obj)) == klass) {
        return ruby_block->block_obj;
     }
     block = Data_Make_Struct(klass, struct BLOCK, blk_mark, blk_free,
data);


Yehuda Katz
Developer | Engine Yard
(ph) 718.877.1325