From: Yehuda Katz Date: 2010-02-28T04:38:30+09:00 Subject: [ruby-core:28364] Small 1.8.7 bug involving proc_alloc --00c09f88cf33975b3704809a28d4 Content-Type: text/plain; charset=ISO-8859-1 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 --00c09f88cf33975b3704809a28d4 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable
I have found a small 1.8.7 bug that prevents=A0proc_alloc from retriev= ing the old Proc object if the Proc has a metaclass. Here's an example:=

def foo
=A0=A0yield
end<= /div>
=A0
def bar(&block)
=A0=A0puts Proc.new.object= _id
=A0=A0def block.foo() "FOO" end
=A0=A0put= s Proc.new.object_id
=A0=A0baz(&block)
end
=A0
def baz(&block)
=A0=A0puts Proc.new.object_id
=A0= =A0yield
end
=A0
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:

=A0=A0 =A0if (!proc && ruby_block->bloc= k_obj && CLASS_OF(ruby_block->block_obj) =3D=3D klass) {
return = ruby_block->block_obj;
=A0=A0 =A0}

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

index 8847= ee5..54a0f46 100644
--- a/eval.c
+++ b/eval.c
@@ -8725,7 +8725,7 @@ pr= oc_alloc(klass, proc)
=A0=A0 =A0 =A0 =A0rb_warn("tried to cr= eate Proc object without a block");
=A0=A0 =A0 }
= =A0
- =A0 =A0if (!proc && ruby_block->block_obj && CLASS_OF(= ruby_block->block_obj) =3D=3D klass) {
+ =A0 =A0if (!proc && ruby_block->block_obj && rb_c= lass_real(CLASS_OF(ruby_block->block_obj)) =3D=3D klass) {
=A0= =A0 =A0 =A0 =A0return ruby_block->block_obj;
=A0=A0 =A0 }
=A0=A0 =A0 block =3D Data_Make_Struct(klass, struct BLOCK, blk_mark, = blk_free, data);


Yehuda Katz
Developer= | Engine Yard
(ph) 718.877.1325
--00c09f88cf33975b3704809a28d4--