mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* enumerator.c: Resolve the method every time an enumeration
method is run, not once when the enumerator is initialized as it was before, so that method_missing() and method (re)definition afterwards are both in effect; pointed out in: [ruby-core:16441] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_8@16108 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
0a56d9d431
commit
cc58638faa
2 changed files with 21 additions and 9 deletions
|
@ -1,3 +1,10 @@
|
||||||
|
Sun Apr 20 21:02:06 2008 Akinori MUSHA <knu@iDaemons.org>
|
||||||
|
|
||||||
|
* enumerator.c: Resolve the method every time an enumeration
|
||||||
|
method is run, not once when the enumerator is initialized as it
|
||||||
|
was before, so that method_missing() and method (re)definition
|
||||||
|
afterwards are both in effect; pointed out in: [ruby-core:16441]
|
||||||
|
|
||||||
Sun Apr 20 17:59:25 2008 Akinori MUSHA <knu@iDaemons.org>
|
Sun Apr 20 17:59:25 2008 Akinori MUSHA <knu@iDaemons.org>
|
||||||
|
|
||||||
* object.c, NEWS, test/ruby/test_symbol.rb: Revert Symbol#to_proc
|
* object.c, NEWS, test/ruby/test_symbol.rb: Revert Symbol#to_proc
|
||||||
|
|
23
enumerator.c
23
enumerator.c
|
@ -21,7 +21,7 @@
|
||||||
* object.
|
* object.
|
||||||
*/
|
*/
|
||||||
VALUE rb_cEnumerator;
|
VALUE rb_cEnumerator;
|
||||||
static VALUE sym_each, sym_call;
|
static VALUE sym_each;
|
||||||
|
|
||||||
VALUE rb_eStopIteration;
|
VALUE rb_eStopIteration;
|
||||||
|
|
||||||
|
@ -37,7 +37,8 @@ proc_call(proc, args)
|
||||||
}
|
}
|
||||||
|
|
||||||
struct enumerator {
|
struct enumerator {
|
||||||
VALUE method;
|
VALUE obj;
|
||||||
|
VALUE meth;
|
||||||
VALUE proc;
|
VALUE proc;
|
||||||
VALUE args;
|
VALUE args;
|
||||||
rb_block_call_func *iter;
|
rb_block_call_func *iter;
|
||||||
|
@ -49,7 +50,8 @@ enumerator_mark(p)
|
||||||
void *p;
|
void *p;
|
||||||
{
|
{
|
||||||
struct enumerator *ptr = p;
|
struct enumerator *ptr = p;
|
||||||
rb_gc_mark(ptr->method);
|
rb_gc_mark(ptr->obj);
|
||||||
|
rb_gc_mark(ptr->meth);
|
||||||
rb_gc_mark(ptr->proc);
|
rb_gc_mark(ptr->proc);
|
||||||
rb_gc_mark(ptr->args);
|
rb_gc_mark(ptr->args);
|
||||||
}
|
}
|
||||||
|
@ -255,7 +257,8 @@ enumerator_init(enum_obj, obj, meth, argc, argv)
|
||||||
{
|
{
|
||||||
struct enumerator *ptr = enumerator_ptr(enum_obj);
|
struct enumerator *ptr = enumerator_ptr(enum_obj);
|
||||||
|
|
||||||
ptr->method = rb_obj_method(obj, meth);
|
ptr->obj = obj;
|
||||||
|
ptr->meth = meth;
|
||||||
if (rb_block_given_p()) {
|
if (rb_block_given_p()) {
|
||||||
ptr->proc = rb_block_proc();
|
ptr->proc = rb_block_proc();
|
||||||
ptr->iter = enumerator_iter_i;
|
ptr->iter = enumerator_iter_i;
|
||||||
|
@ -312,7 +315,8 @@ enumerator_init_copy(obj, orig)
|
||||||
ptr0 = enumerator_ptr(orig);
|
ptr0 = enumerator_ptr(orig);
|
||||||
ptr1 = enumerator_ptr(obj);
|
ptr1 = enumerator_ptr(obj);
|
||||||
|
|
||||||
ptr1->method = ptr0->method;
|
ptr1->obj = ptr0->obj;
|
||||||
|
ptr1->meth = ptr0->meth;
|
||||||
ptr1->proc = ptr0->proc;
|
ptr1->proc = ptr0->proc;
|
||||||
ptr1->iter = ptr0->iter;
|
ptr1->iter = ptr0->iter;
|
||||||
ptr1->args = ptr0->args;
|
ptr1->args = ptr0->args;
|
||||||
|
@ -345,6 +349,7 @@ enumerator_each(obj)
|
||||||
struct enumerator *e;
|
struct enumerator *e;
|
||||||
int argc = 0;
|
int argc = 0;
|
||||||
VALUE *argv = 0;
|
VALUE *argv = 0;
|
||||||
|
VALUE method;
|
||||||
|
|
||||||
if (!rb_block_given_p()) return obj;
|
if (!rb_block_given_p()) return obj;
|
||||||
e = enumerator_ptr(obj);
|
e = enumerator_ptr(obj);
|
||||||
|
@ -352,7 +357,7 @@ enumerator_each(obj)
|
||||||
argc = RARRAY_LEN(e->args);
|
argc = RARRAY_LEN(e->args);
|
||||||
argv = RARRAY_PTR(e->args);
|
argv = RARRAY_PTR(e->args);
|
||||||
}
|
}
|
||||||
return rb_block_call(e->method, SYM2ID(sym_call), argc, argv, e->iter, (VALUE)e);
|
return rb_block_call(e->obj, rb_to_id(e->meth), argc, argv, e->iter, (VALUE)e);
|
||||||
}
|
}
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
|
@ -381,13 +386,14 @@ enumerator_with_index(obj)
|
||||||
VALUE memo = 0;
|
VALUE memo = 0;
|
||||||
int argc = 0;
|
int argc = 0;
|
||||||
VALUE *argv = 0;
|
VALUE *argv = 0;
|
||||||
|
VALUE method;
|
||||||
|
|
||||||
RETURN_ENUMERATOR(obj, 0, 0);
|
RETURN_ENUMERATOR(obj, 0, 0);
|
||||||
if (e->args) {
|
if (e->args) {
|
||||||
argc = RARRAY_LEN(e->args);
|
argc = RARRAY_LEN(e->args);
|
||||||
argv = RARRAY_PTR(e->args);
|
argv = RARRAY_PTR(e->args);
|
||||||
}
|
}
|
||||||
return rb_block_call(e->method, SYM2ID(sym_call), argc, argv,
|
return rb_block_call(e->obj, rb_to_id(e->meth), argc, argv,
|
||||||
enumerator_with_index_i, (VALUE)&memo);
|
enumerator_with_index_i, (VALUE)&memo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -454,8 +460,7 @@ Init_Enumerator()
|
||||||
|
|
||||||
rb_eStopIteration = rb_define_class("StopIteration", rb_eIndexError);
|
rb_eStopIteration = rb_define_class("StopIteration", rb_eIndexError);
|
||||||
|
|
||||||
sym_each = ID2SYM(rb_intern("each"));
|
sym_each = ID2SYM(rb_intern("each"));
|
||||||
sym_call = ID2SYM(rb_intern("call"));
|
|
||||||
|
|
||||||
rb_provide("enumerator.so"); /* for backward compatibility */
|
rb_provide("enumerator.so"); /* for backward compatibility */
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue