Index: array.c
===================================================================
RCS file: /cvs/ruby/src/ruby/array.c,v
retrieving revision 1.175
diff -U2 -p -r1.175 array.c
--- array.c	10 Aug 2005 01:39:24 -0000	1.175
+++ array.c	30 Aug 2005 10:03:03 -0000
@@ -993,4 +993,5 @@ rb_ary_index(argc, argv, ary)
 
     if (rb_scan_args(argc, argv, "01", &val) == 0) {
+	RETURN_ENUMERATOR(ary, 0, 0);
 	for (i=0; i<RARRAY(ary)->len; i++) {
 	    if (RTEST(rb_yield(RARRAY(ary)->ptr[i]))) {
@@ -1034,4 +1035,5 @@ rb_ary_rindex(argc, argv, ary)
     if (rb_scan_args(argc, argv, "01", &val) == 0) {
 	while (i--) {
+	    RETURN_ENUMERATOR(ary, 0, 0);
 	    if (RTEST(rb_yield(RARRAY(ary)->ptr[i])))
 		return LONG2NUM(i);
@@ -1247,4 +1249,5 @@ rb_ary_each(ary)
     long i;
 
+    RETURN_ENUMERATOR(ary, 0, 0);
     for (i=0; i<RARRAY(ary)->len; i++) {
 	rb_yield(RARRAY(ary)->ptr[i]);
@@ -1274,4 +1277,5 @@ rb_ary_each_index(ary)
     long i;
 
+    RETURN_ENUMERATOR(ary, 0, 0);
     for (i=0; i<RARRAY(ary)->len; i++) {
 	rb_yield(LONG2NUM(i));
@@ -1301,4 +1305,5 @@ rb_ary_reverse_each(ary)
     long len = RARRAY(ary)->len;
 
+    RETURN_ENUMERATOR(ary, 0, 0);
     while (len--) {
 	rb_yield(RARRAY(ary)->ptr[len]);
@@ -1737,8 +1742,5 @@ rb_ary_collect(ary)
     VALUE collect;
 
-    if (!rb_block_given_p()) {
-	return rb_ary_new4(RARRAY(ary)->len, RARRAY(ary)->ptr);
-    }
-
+    RETURN_ENUMERATOR(ary, 0, 0);
     collect = rb_ary_new2(RARRAY(ary)->len);
     for (i = 0; i < RARRAY(ary)->len; i++) {
@@ -1768,4 +1770,5 @@ rb_ary_collect_bang(ary)
     long i;
 
+    RETURN_ENUMERATOR(ary, 0, 0);
     rb_ary_modify(ary);
     for (i = 0; i < RARRAY(ary)->len; i++) {
@@ -1852,4 +1855,5 @@ rb_ary_select(ary)
     long i;
 
+    RETURN_ENUMERATOR(ary, 0, 0);
     result = rb_ary_new2(RARRAY(ary)->len);
     for (i = 0; i < RARRAY(ary)->len; i++) {
@@ -2028,4 +2032,5 @@ rb_ary_reject_bang(ary)
     long i1, i2;
 
+    RETURN_ENUMERATOR(ary, 0, 0);
     rb_ary_modify(ary);
     for (i1 = i2 = 0; i1 < RARRAY(ary)->len; i1++) {
@@ -2056,4 +2061,5 @@ rb_ary_reject(ary)
     VALUE ary;
 {
+    RETURN_ENUMERATOR(ary, 0, 0);
     ary = rb_ary_dup(ary);
     rb_ary_reject_bang(ary);
Index: dir.c
===================================================================
RCS file: /cvs/ruby/src/ruby/dir.c,v
retrieving revision 1.142
diff -U2 -p -r1.142 dir.c
--- dir.c	27 Jul 2005 07:27:19 -0000	1.142
+++ dir.c	30 Aug 2005 09:34:55 -0000
@@ -543,4 +543,5 @@ dir_each(dir)
     struct dirent *dp;
 
+    RETURN_ENUMERATOR(dir, 0, 0);
     GetDIR(dir, dirp);
     rewinddir(dirp->dir);
Index: enum.c
===================================================================
RCS file: /cvs/ruby/src/ruby/enum.c,v
retrieving revision 1.60
diff -U2 -p -r1.60 enum.c
--- enum.c	14 Jul 2005 16:18:44 -0000	1.60
+++ enum.c	30 Aug 2005 10:26:06 -0000
@@ -18,13 +18,4 @@ VALUE rb_mEnumerable;
 static ID id_each, id_eqq, id_cmp;
 
-static VALUE
-enumeratorize(argc, argv, obj)
-    int argc;
-    VALUE *argv;
-    VALUE obj;
-{
-    return rb_enumeratorize(obj, ID2SYM(rb_frame_this_func()), argc, argv);
-}
-
 VALUE
 rb_each(obj)
@@ -124,6 +115,5 @@ enum_find(argc, argv, obj)
 
     rb_scan_args(argc, argv, "01", &if_none);
-    if (!rb_block_given_p())
-	return enumeratorize(argc, argv, obj);
+    RETURN_ENUMERATOR(obj, argc, argv);
     rb_iterate(rb_each, obj, find_i, (VALUE)&memo);
     if (memo != Qundef) {
@@ -165,5 +155,5 @@ enum_find_all(obj)
     VALUE ary;
     
-    if (!rb_block_given_p()) return enumeratorize(0, 0, obj);
+    RETURN_ENUMERATOR(obj, 0, 0);
 
     ary = rb_ary_new();
@@ -200,5 +190,5 @@ enum_reject(obj)
     VALUE ary;
     
-    if (!rb_block_given_p()) return enumeratorize(0, 0, obj);
+    RETURN_ENUMERATOR(obj, 0, 0);
 
     ary = rb_ary_new();
@@ -245,5 +235,5 @@ enum_collect(obj)
     VALUE ary;
 
-    if (!rb_block_given_p()) return enumeratorize(0, 0, obj);
+    RETURN_ENUMERATOR(obj, 0, 0);
 
     ary = rb_ary_new();
@@ -364,5 +354,5 @@ enum_partition(obj)
     VALUE ary[2];
 
-    if (!rb_block_given_p()) return enumeratorize(0, 0, obj);
+    RETURN_ENUMERATOR(obj, 0, 0);
 
     ary[0] = rb_ary_new();
@@ -499,5 +489,5 @@ enum_sort_by(obj)
     long i;
 
-    if (!rb_block_given_p()) return enumeratorize(0, 0, obj);
+    RETURN_ENUMERATOR(obj, 0, 0);
 
     if (TYPE(obj) == T_ARRAY) {
@@ -788,5 +778,5 @@ enum_min_by(obj)
     VALUE memo[2];
 
-    if (!rb_block_given_p()) return enumeratorize(0, 0, obj);
+    RETURN_ENUMERATOR(obj, 0, 0);
 
     memo[0] = Qundef;
@@ -832,5 +822,5 @@ enum_max_by(obj)
     VALUE memo[2];
 
-    if (!rb_block_given_p()) return enumeratorize(0, 0, obj);
+    RETURN_ENUMERATOR(obj, 0, 0);
 
     memo[0] = Qundef;
@@ -908,5 +898,5 @@ enum_each_with_index(obj)
     VALUE memo = 0;
 
-    if (!rb_block_given_p()) return enumeratorize(0, 0, obj);
+    RETURN_ENUMERATOR(obj, 0, 0);
 
     rb_iterate(rb_each, obj, each_with_index_i, (VALUE)&memo);
Index: hash.c
===================================================================
RCS file: /cvs/ruby/src/ruby/hash.c,v
retrieving revision 1.155
diff -U2 -p -r1.155 hash.c
--- hash.c	28 Jul 2005 08:16:34 -0000	1.155
+++ hash.c	30 Aug 2005 10:05:19 -0000
@@ -834,4 +834,5 @@ rb_hash_select(hash)
     VALUE result;
 
+    RETURN_ENUMERATOR(hash, 0, 0);
     result = rb_ary_new();
     rb_hash_foreach(hash, select_i, result);
@@ -1012,4 +1013,5 @@ rb_hash_each_value(hash)
     VALUE hash;
 {
+    RETURN_ENUMERATOR(hash, 0, 0);
     rb_hash_foreach(hash, each_value_i, 0);
     return hash;
@@ -1044,4 +1046,5 @@ rb_hash_each_key(hash)
     VALUE hash;
 {
+    RETURN_ENUMERATOR(hash, 0, 0);
     rb_hash_foreach(hash, each_key_i, 0);
     return hash;
@@ -1078,4 +1081,5 @@ rb_hash_each_pair(hash)
     VALUE hash;
 {
+    RETURN_ENUMERATOR(hash, 0, 0);
     rb_hash_foreach(hash, each_pair_i, 0);
     return hash;
@@ -1115,4 +1119,5 @@ rb_hash_each(hash)
     VALUE hash;
 {
+    RETURN_ENUMERATOR(hash, 0, 0);
     rb_hash_foreach(hash, each_i, 0);
     return hash;
@@ -1931,4 +1936,5 @@ env_each_key(ehash)
     long i;
 
+    RETURN_ENUMERATOR(ehash, 0, 0);
     rb_secure(4);
     keys = env_keys();
@@ -1966,4 +1972,5 @@ env_each_value(ehash)
     long i;
 
+    RETURN_ENUMERATOR(ehash, 0, 0);
     rb_secure(4);
     values = env_values();
@@ -2011,4 +2018,5 @@ env_each(ehash)
     VALUE ehash;
 {
+    RETURN_ENUMERATOR(ehash, 0, 0);
     return env_each_i(ehash, Qfalse);
 }
@@ -2018,4 +2026,5 @@ env_each_pair(ehash)
     VALUE ehash;
 {
+    RETURN_ENUMERATOR(ehash, 0, 0);
     return env_each_i(ehash, Qtrue);
 }
@@ -2068,9 +2077,11 @@ env_values_at(argc, argv)
 
 static VALUE
-env_select()
+env_select(ehash)
+    VALUE ehash;
 {
     VALUE result;
     char **env;
 
+    RETURN_ENUMERATOR(ehash, 0, 0);
     rb_secure(4);
     result = rb_ary_new();
Index: intern.h
===================================================================
RCS file: /cvs/ruby/src/ruby/intern.h,v
retrieving revision 1.177
diff -U2 -p -r1.177 intern.h
--- intern.h	14 Aug 2005 22:25:09 -0000	1.177
+++ intern.h	30 Aug 2005 09:31:48 -0000
@@ -144,4 +144,9 @@ NORETURN(void rb_cmperr _((VALUE, VALUE)
 /* enumerator.c */
 VALUE rb_enumeratorize _((VALUE, VALUE, int, VALUE *));
+#define RETURN_ENUMERATOR(obj, argc, argv) do {				\
+	if (!rb_block_given_p())					\
+	    return rb_enumeratorize(obj, ID2SYM(rb_frame_this_func()),	\
+				    argc, argv);			\
+    } while (0)
 /* error.c */
 RUBY_EXTERN int ruby_nerrs;
Index: io.c
===================================================================
RCS file: /cvs/ruby/src/ruby/io.c,v
retrieving revision 1.375
diff -U2 -p -r1.375 io.c
--- io.c	27 Jul 2005 07:27:18 -0000	1.375
+++ io.c	30 Aug 2005 09:41:51 -0000
@@ -1852,4 +1852,5 @@ rb_io_each_line(argc, argv, io)
     VALUE rs;
 
+    RETURN_ENUMERATOR(io, argc, argv);
     if (argc == 0) {
 	rs = rb_rs;
@@ -1886,4 +1887,5 @@ rb_io_each_byte(io)
     int c;
 
+    RETURN_ENUMERATOR(io, 0, 0);
     GetOpenFile(io, fptr);
 
@@ -5154,11 +5156,13 @@ io_s_foreach(arg)
 
 static VALUE
-rb_io_s_foreach(argc, argv)
+rb_io_s_foreach(argc, argv, self)
     int argc;
     VALUE *argv;
+    VALUE self;
 {
     VALUE fname;
     struct foreach_arg arg;
 
+    RETURN_ENUMERATOR(self, argc, argv);
     rb_scan_args(argc, argv, "11", &fname, &arg.sep);
     FilePathValue(fname);
@@ -5454,10 +5458,12 @@ argf_readchar()
 
 static VALUE
-argf_each_line(argc, argv)
+argf_each_line(argc, argv, self)
     int argc;
     VALUE *argv;
+    VALUE self;
 {
     VALUE str;
 
+    RETURN_ENUMERATOR(self, argc, argv);
     if (!next_argv()) return Qnil;
     if (TYPE(current_file) != T_FILE) {
@@ -5475,8 +5481,10 @@ argf_each_line(argc, argv)
 
 static VALUE
-argf_each_byte()
+argf_each_byte(self)
+    VALUE self;
 {
     VALUE byte;
 
+    RETURN_ENUMERATOR(self, 0, 0);
     while (!NIL_P(byte = argf_getc())) {
 	rb_yield(byte);
Index: range.c
===================================================================
RCS file: /cvs/ruby/src/ruby/range.c,v
retrieving revision 1.73
diff -U2 -p -r1.73 range.c
--- range.c	14 Aug 2005 15:39:22 -0000	1.73
+++ range.c	30 Aug 2005 09:45:29 -0000
@@ -304,4 +304,6 @@ range_step(argc, argv, range)
     long unit;
 
+    RETURN_ENUMERATOR(range, argc, argv);
+
     b = rb_ivar_get(range, id_beg);
     e = rb_ivar_get(range, id_end);
@@ -393,4 +395,6 @@ range_each(range)
     VALUE beg, end;
 
+    RETURN_ENUMERATOR(range, 0, 0);
+
     beg = rb_ivar_get(range, id_beg);
     end = rb_ivar_get(range, id_end);
Index: string.c
===================================================================
RCS file: /cvs/ruby/src/ruby/string.c,v
retrieving revision 1.231
diff -U2 -p -r1.231 string.c
--- string.c	23 Jul 2005 01:02:10 -0000	1.231
+++ string.c	30 Aug 2005 09:36:18 -0000
@@ -2049,13 +2049,15 @@ str_gsub(argc, argv, str, bang)
     int tainted = 0;
 
-    if (argc == 1 && rb_block_given_p()) {
+    switch (argc) {
+      case 1:
+	RETURN_ENUMERATOR(str, argc, argv);
 	iter = 1;
-    }
-    else if (argc == 2) {
+	break;
+      case 2:
 	repl = argv[1];
 	StringValue(repl);
 	if (OBJ_TAINTED(repl)) tainted = 1;
-    }
-    else {
+	break;
+      default:
 	rb_raise(rb_eArgError, "wrong number of arguments (%d for 2)", argc);
     }
@@ -3693,4 +3695,6 @@ rb_str_each_line(argc, argv, str)
     }
 
+    RETURN_ENUMERATOR(str, argc, argv);
+
     if (NIL_P(rs)) {
 	rb_yield(str);
@@ -3752,4 +3756,5 @@ rb_str_each_byte(str)
     long i;
 
+    RETURN_ENUMERATOR(str, 0, 0);
     for (i=0; i<RSTRING(str)->len; i++) {
 	rb_yield(INT2FIX(RSTRING(str)->ptr[i] & 0xff));
@@ -4268,4 +4273,6 @@ rb_str_scan(str, pat)
     VALUE match = Qnil;
 
+    RETURN_ENUMERATOR(str, 1, &pat);
+
     pat = get_pat(pat, 1);
     if (!rb_block_given_p()) {
Index: struct.c
===================================================================
RCS file: /cvs/ruby/src/ruby/struct.c,v
retrieving revision 1.67
diff -U2 -p -r1.67 struct.c
--- struct.c	23 Jul 2005 01:02:11 -0000	1.67
+++ struct.c	30 Aug 2005 10:32:07 -0000
@@ -429,4 +429,5 @@ rb_struct_each(s)
     long i;
 
+    RETURN_ENUMERATOR(s, 0, 0);
     for (i=0; i<RSTRUCT(s)->len; i++) {
 	rb_yield(RSTRUCT(s)->ptr[i]);
@@ -460,4 +461,5 @@ rb_struct_each_pair(s)
     long i;
 
+    RETURN_ENUMERATOR(s, 0, 0);
     members = rb_struct_members(s);
     for (i=0; i<RSTRUCT(s)->len; i++) {
