* array.c, dir.c, enum.c, hash.c, io.c, range.c, string.c, struct.c:

let enumerable methods return Enumerator.  [ruby-dev:26924]

* intern.h (RETURN_ENUMERATOR): utility macro for enumerable methods.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9053 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2005-08-30 14:49:51 +00:00
parent 87e8b14cc4
commit 74433fd300
10 changed files with 73 additions and 32 deletions

View File

@ -1,3 +1,10 @@
Tue Aug 30 23:49:34 2005 Nobuyoshi Nakada <nobu@ruby-lang.org>
* array.c, dir.c, enum.c, hash.c, io.c, range.c, string.c, struct.c:
let enumerable methods return Enumerator. [ruby-dev:26924]
* intern.h (RETURN_ENUMERATOR): utility macro for enumerable methods.
Tue Aug 30 23:25:45 2005 NAKAMURA, Hiroshi <nakahiro@sarion.co.jp> Tue Aug 30 23:25:45 2005 NAKAMURA, Hiroshi <nakahiro@sarion.co.jp>
* lib/debug.rb: no need to restart at exit. * lib/debug.rb: no need to restart at exit.

14
array.c
View File

@ -992,6 +992,7 @@ rb_ary_index(argc, argv, ary)
long i; long i;
if (rb_scan_args(argc, argv, "01", &val) == 0) { if (rb_scan_args(argc, argv, "01", &val) == 0) {
RETURN_ENUMERATOR(ary, 0, 0);
for (i=0; i<RARRAY(ary)->len; i++) { for (i=0; i<RARRAY(ary)->len; i++) {
if (RTEST(rb_yield(RARRAY(ary)->ptr[i]))) { if (RTEST(rb_yield(RARRAY(ary)->ptr[i]))) {
return LONG2NUM(i); return LONG2NUM(i);
@ -1033,6 +1034,7 @@ rb_ary_rindex(argc, argv, ary)
if (rb_scan_args(argc, argv, "01", &val) == 0) { if (rb_scan_args(argc, argv, "01", &val) == 0) {
while (i--) { while (i--) {
RETURN_ENUMERATOR(ary, 0, 0);
if (RTEST(rb_yield(RARRAY(ary)->ptr[i]))) if (RTEST(rb_yield(RARRAY(ary)->ptr[i])))
return LONG2NUM(i); return LONG2NUM(i);
if (i > RARRAY(ary)->len) { if (i > RARRAY(ary)->len) {
@ -1246,6 +1248,7 @@ rb_ary_each(ary)
{ {
long i; long i;
RETURN_ENUMERATOR(ary, 0, 0);
for (i=0; i<RARRAY(ary)->len; i++) { for (i=0; i<RARRAY(ary)->len; i++) {
rb_yield(RARRAY(ary)->ptr[i]); rb_yield(RARRAY(ary)->ptr[i]);
} }
@ -1273,6 +1276,7 @@ rb_ary_each_index(ary)
{ {
long i; long i;
RETURN_ENUMERATOR(ary, 0, 0);
for (i=0; i<RARRAY(ary)->len; i++) { for (i=0; i<RARRAY(ary)->len; i++) {
rb_yield(LONG2NUM(i)); rb_yield(LONG2NUM(i));
} }
@ -1300,6 +1304,7 @@ rb_ary_reverse_each(ary)
{ {
long len = RARRAY(ary)->len; long len = RARRAY(ary)->len;
RETURN_ENUMERATOR(ary, 0, 0);
while (len--) { while (len--) {
rb_yield(RARRAY(ary)->ptr[len]); rb_yield(RARRAY(ary)->ptr[len]);
if (RARRAY(ary)->len < len) { if (RARRAY(ary)->len < len) {
@ -1736,10 +1741,7 @@ rb_ary_collect(ary)
long i; long i;
VALUE collect; VALUE collect;
if (!rb_block_given_p()) { RETURN_ENUMERATOR(ary, 0, 0);
return rb_ary_new4(RARRAY(ary)->len, RARRAY(ary)->ptr);
}
collect = rb_ary_new2(RARRAY(ary)->len); collect = rb_ary_new2(RARRAY(ary)->len);
for (i = 0; i < RARRAY(ary)->len; i++) { for (i = 0; i < RARRAY(ary)->len; i++) {
rb_ary_push(collect, rb_yield(RARRAY(ary)->ptr[i])); rb_ary_push(collect, rb_yield(RARRAY(ary)->ptr[i]));
@ -1767,6 +1769,7 @@ rb_ary_collect_bang(ary)
{ {
long i; long i;
RETURN_ENUMERATOR(ary, 0, 0);
rb_ary_modify(ary); rb_ary_modify(ary);
for (i = 0; i < RARRAY(ary)->len; i++) { for (i = 0; i < RARRAY(ary)->len; i++) {
rb_ary_store(ary, i, rb_yield(RARRAY(ary)->ptr[i])); rb_ary_store(ary, i, rb_yield(RARRAY(ary)->ptr[i]));
@ -1851,6 +1854,7 @@ rb_ary_select(ary)
VALUE result; VALUE result;
long i; long i;
RETURN_ENUMERATOR(ary, 0, 0);
result = rb_ary_new2(RARRAY(ary)->len); result = rb_ary_new2(RARRAY(ary)->len);
for (i = 0; i < RARRAY(ary)->len; i++) { for (i = 0; i < RARRAY(ary)->len; i++) {
if (RTEST(rb_yield(RARRAY(ary)->ptr[i]))) { if (RTEST(rb_yield(RARRAY(ary)->ptr[i]))) {
@ -2027,6 +2031,7 @@ rb_ary_reject_bang(ary)
{ {
long i1, i2; long i1, i2;
RETURN_ENUMERATOR(ary, 0, 0);
rb_ary_modify(ary); rb_ary_modify(ary);
for (i1 = i2 = 0; i1 < RARRAY(ary)->len; i1++) { for (i1 = i2 = 0; i1 < RARRAY(ary)->len; i1++) {
VALUE v = RARRAY(ary)->ptr[i1]; VALUE v = RARRAY(ary)->ptr[i1];
@ -2055,6 +2060,7 @@ static VALUE
rb_ary_reject(ary) rb_ary_reject(ary)
VALUE ary; VALUE ary;
{ {
RETURN_ENUMERATOR(ary, 0, 0);
ary = rb_ary_dup(ary); ary = rb_ary_dup(ary);
rb_ary_reject_bang(ary); rb_ary_reject_bang(ary);
return ary; return ary;

1
dir.c
View File

@ -542,6 +542,7 @@ dir_each(dir)
struct dir_data *dirp; struct dir_data *dirp;
struct dirent *dp; struct dirent *dp;
RETURN_ENUMERATOR(dir, 0, 0);
GetDIR(dir, dirp); GetDIR(dir, dirp);
rewinddir(dirp->dir); rewinddir(dirp->dir);
for (dp = readdir(dirp->dir); dp != NULL; dp = readdir(dirp->dir)) { for (dp = readdir(dirp->dir); dp != NULL; dp = readdir(dirp->dir)) {

28
enum.c
View File

@ -17,15 +17,6 @@
VALUE rb_mEnumerable; VALUE rb_mEnumerable;
static ID id_each, id_eqq, id_cmp; 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 VALUE
rb_each(obj) rb_each(obj)
VALUE obj; VALUE obj;
@ -123,8 +114,7 @@ enum_find(argc, argv, obj)
VALUE if_none; VALUE if_none;
rb_scan_args(argc, argv, "01", &if_none); rb_scan_args(argc, argv, "01", &if_none);
if (!rb_block_given_p()) RETURN_ENUMERATOR(obj, argc, argv);
return enumeratorize(argc, argv, obj);
rb_iterate(rb_each, obj, find_i, (VALUE)&memo); rb_iterate(rb_each, obj, find_i, (VALUE)&memo);
if (memo != Qundef) { if (memo != Qundef) {
return memo; return memo;
@ -164,7 +154,7 @@ enum_find_all(obj)
{ {
VALUE ary; VALUE ary;
if (!rb_block_given_p()) return enumeratorize(0, 0, obj); RETURN_ENUMERATOR(obj, 0, 0);
ary = rb_ary_new(); ary = rb_ary_new();
rb_iterate(rb_each, obj, find_all_i, ary); rb_iterate(rb_each, obj, find_all_i, ary);
@ -199,7 +189,7 @@ enum_reject(obj)
{ {
VALUE ary; VALUE ary;
if (!rb_block_given_p()) return enumeratorize(0, 0, obj); RETURN_ENUMERATOR(obj, 0, 0);
ary = rb_ary_new(); ary = rb_ary_new();
rb_iterate(rb_each, obj, reject_i, ary); rb_iterate(rb_each, obj, reject_i, ary);
@ -244,7 +234,7 @@ enum_collect(obj)
{ {
VALUE ary; VALUE ary;
if (!rb_block_given_p()) return enumeratorize(0, 0, obj); RETURN_ENUMERATOR(obj, 0, 0);
ary = rb_ary_new(); ary = rb_ary_new();
rb_iterate(rb_each, obj, collect_i, ary); rb_iterate(rb_each, obj, collect_i, ary);
@ -363,7 +353,7 @@ enum_partition(obj)
{ {
VALUE ary[2]; VALUE ary[2];
if (!rb_block_given_p()) return enumeratorize(0, 0, obj); RETURN_ENUMERATOR(obj, 0, 0);
ary[0] = rb_ary_new(); ary[0] = rb_ary_new();
ary[1] = rb_ary_new(); ary[1] = rb_ary_new();
@ -498,7 +488,7 @@ enum_sort_by(obj)
VALUE ary; VALUE ary;
long i; long i;
if (!rb_block_given_p()) return enumeratorize(0, 0, obj); RETURN_ENUMERATOR(obj, 0, 0);
if (TYPE(obj) == T_ARRAY) { if (TYPE(obj) == T_ARRAY) {
ary = rb_ary_new2(RARRAY(obj)->len); ary = rb_ary_new2(RARRAY(obj)->len);
@ -787,7 +777,7 @@ enum_min_by(obj)
{ {
VALUE memo[2]; VALUE memo[2];
if (!rb_block_given_p()) return enumeratorize(0, 0, obj); RETURN_ENUMERATOR(obj, 0, 0);
memo[0] = Qundef; memo[0] = Qundef;
memo[1] = Qnil; memo[1] = Qnil;
@ -831,7 +821,7 @@ enum_max_by(obj)
{ {
VALUE memo[2]; VALUE memo[2];
if (!rb_block_given_p()) return enumeratorize(0, 0, obj); RETURN_ENUMERATOR(obj, 0, 0);
memo[0] = Qundef; memo[0] = Qundef;
memo[1] = Qnil; memo[1] = Qnil;
@ -907,7 +897,7 @@ enum_each_with_index(obj)
{ {
VALUE memo = 0; 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); rb_iterate(rb_each, obj, each_with_index_i, (VALUE)&memo);
return obj; return obj;

13
hash.c
View File

@ -833,6 +833,7 @@ rb_hash_select(hash)
{ {
VALUE result; VALUE result;
RETURN_ENUMERATOR(hash, 0, 0);
result = rb_ary_new(); result = rb_ary_new();
rb_hash_foreach(hash, select_i, result); rb_hash_foreach(hash, select_i, result);
return result; return result;
@ -1011,6 +1012,7 @@ static VALUE
rb_hash_each_value(hash) rb_hash_each_value(hash)
VALUE hash; VALUE hash;
{ {
RETURN_ENUMERATOR(hash, 0, 0);
rb_hash_foreach(hash, each_value_i, 0); rb_hash_foreach(hash, each_value_i, 0);
return hash; return hash;
} }
@ -1043,6 +1045,7 @@ static VALUE
rb_hash_each_key(hash) rb_hash_each_key(hash)
VALUE hash; VALUE hash;
{ {
RETURN_ENUMERATOR(hash, 0, 0);
rb_hash_foreach(hash, each_key_i, 0); rb_hash_foreach(hash, each_key_i, 0);
return hash; return hash;
} }
@ -1077,6 +1080,7 @@ static VALUE
rb_hash_each_pair(hash) rb_hash_each_pair(hash)
VALUE hash; VALUE hash;
{ {
RETURN_ENUMERATOR(hash, 0, 0);
rb_hash_foreach(hash, each_pair_i, 0); rb_hash_foreach(hash, each_pair_i, 0);
return hash; return hash;
} }
@ -1114,6 +1118,7 @@ static VALUE
rb_hash_each(hash) rb_hash_each(hash)
VALUE hash; VALUE hash;
{ {
RETURN_ENUMERATOR(hash, 0, 0);
rb_hash_foreach(hash, each_i, 0); rb_hash_foreach(hash, each_i, 0);
return hash; return hash;
} }
@ -1930,6 +1935,7 @@ env_each_key(ehash)
VALUE keys; VALUE keys;
long i; long i;
RETURN_ENUMERATOR(ehash, 0, 0);
rb_secure(4); rb_secure(4);
keys = env_keys(); keys = env_keys();
for (i=0; i<RARRAY(keys)->len; i++) { for (i=0; i<RARRAY(keys)->len; i++) {
@ -1965,6 +1971,7 @@ env_each_value(ehash)
VALUE values = env_values(); VALUE values = env_values();
long i; long i;
RETURN_ENUMERATOR(ehash, 0, 0);
rb_secure(4); rb_secure(4);
values = env_values(); values = env_values();
for (i=0; i<RARRAY(values)->len; i++) { for (i=0; i<RARRAY(values)->len; i++) {
@ -2010,6 +2017,7 @@ static VALUE
env_each(ehash) env_each(ehash)
VALUE ehash; VALUE ehash;
{ {
RETURN_ENUMERATOR(ehash, 0, 0);
return env_each_i(ehash, Qfalse); return env_each_i(ehash, Qfalse);
} }
@ -2017,6 +2025,7 @@ static VALUE
env_each_pair(ehash) env_each_pair(ehash)
VALUE ehash; VALUE ehash;
{ {
RETURN_ENUMERATOR(ehash, 0, 0);
return env_each_i(ehash, Qtrue); return env_each_i(ehash, Qtrue);
} }
@ -2067,11 +2076,13 @@ env_values_at(argc, argv)
} }
static VALUE static VALUE
env_select() env_select(ehash)
VALUE ehash;
{ {
VALUE result; VALUE result;
char **env; char **env;
RETURN_ENUMERATOR(ehash, 0, 0);
rb_secure(4); rb_secure(4);
result = rb_ary_new(); result = rb_ary_new();
env = GET_ENVIRON(environ); env = GET_ENVIRON(environ);

View File

@ -143,6 +143,11 @@ NORETURN(void rb_cmperr _((VALUE, VALUE)));
/* enum.c */ /* enum.c */
/* enumerator.c */ /* enumerator.c */
VALUE rb_enumeratorize _((VALUE, VALUE, int, VALUE *)); 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 */ /* error.c */
RUBY_EXTERN int ruby_nerrs; RUBY_EXTERN int ruby_nerrs;
VALUE rb_exc_new _((VALUE, const char*, long)); VALUE rb_exc_new _((VALUE, const char*, long));

14
io.c
View File

@ -1851,6 +1851,7 @@ rb_io_each_line(argc, argv, io)
VALUE str; VALUE str;
VALUE rs; VALUE rs;
RETURN_ENUMERATOR(io, argc, argv);
if (argc == 0) { if (argc == 0) {
rs = rb_rs; rs = rb_rs;
} }
@ -1885,6 +1886,7 @@ rb_io_each_byte(io)
OpenFile *fptr; OpenFile *fptr;
int c; int c;
RETURN_ENUMERATOR(io, 0, 0);
GetOpenFile(io, fptr); GetOpenFile(io, fptr);
for (;;) { for (;;) {
@ -5153,13 +5155,15 @@ io_s_foreach(arg)
*/ */
static VALUE static VALUE
rb_io_s_foreach(argc, argv) rb_io_s_foreach(argc, argv, self)
int argc; int argc;
VALUE *argv; VALUE *argv;
VALUE self;
{ {
VALUE fname; VALUE fname;
struct foreach_arg arg; struct foreach_arg arg;
RETURN_ENUMERATOR(self, argc, argv);
rb_scan_args(argc, argv, "11", &fname, &arg.sep); rb_scan_args(argc, argv, "11", &fname, &arg.sep);
FilePathValue(fname); FilePathValue(fname);
if (argc == 1) { if (argc == 1) {
@ -5453,12 +5457,14 @@ argf_readchar()
} }
static VALUE static VALUE
argf_each_line(argc, argv) argf_each_line(argc, argv, self)
int argc; int argc;
VALUE *argv; VALUE *argv;
VALUE self;
{ {
VALUE str; VALUE str;
RETURN_ENUMERATOR(self, argc, argv);
if (!next_argv()) return Qnil; if (!next_argv()) return Qnil;
if (TYPE(current_file) != T_FILE) { if (TYPE(current_file) != T_FILE) {
for (;;) { for (;;) {
@ -5474,10 +5480,12 @@ argf_each_line(argc, argv)
} }
static VALUE static VALUE
argf_each_byte() argf_each_byte(self)
VALUE self;
{ {
VALUE byte; VALUE byte;
RETURN_ENUMERATOR(self, 0, 0);
while (!NIL_P(byte = argf_getc())) { while (!NIL_P(byte = argf_getc())) {
rb_yield(byte); rb_yield(byte);
} }

View File

@ -303,6 +303,8 @@ range_step(argc, argv, range)
VALUE b, e, step; VALUE b, e, step;
long unit; long unit;
RETURN_ENUMERATOR(range, argc, argv);
b = rb_ivar_get(range, id_beg); b = rb_ivar_get(range, id_beg);
e = rb_ivar_get(range, id_end); e = rb_ivar_get(range, id_end);
if (rb_scan_args(argc, argv, "01", &step) == 0) { if (rb_scan_args(argc, argv, "01", &step) == 0) {
@ -392,6 +394,8 @@ range_each(range)
{ {
VALUE beg, end; VALUE beg, end;
RETURN_ENUMERATOR(range, 0, 0);
beg = rb_ivar_get(range, id_beg); beg = rb_ivar_get(range, id_beg);
end = rb_ivar_get(range, id_end); end = rb_ivar_get(range, id_end);

View File

@ -2048,15 +2048,17 @@ str_gsub(argc, argv, str, bang)
char *buf, *bp, *sp, *cp; char *buf, *bp, *sp, *cp;
int tainted = 0; int tainted = 0;
if (argc == 1 && rb_block_given_p()) { switch (argc) {
case 1:
RETURN_ENUMERATOR(str, argc, argv);
iter = 1; iter = 1;
} break;
else if (argc == 2) { case 2:
repl = argv[1]; repl = argv[1];
StringValue(repl); StringValue(repl);
if (OBJ_TAINTED(repl)) tainted = 1; if (OBJ_TAINTED(repl)) tainted = 1;
} break;
else { default:
rb_raise(rb_eArgError, "wrong number of arguments (%d for 2)", argc); rb_raise(rb_eArgError, "wrong number of arguments (%d for 2)", argc);
} }
@ -3692,6 +3694,8 @@ rb_str_each_line(argc, argv, str)
rs = rb_rs; rs = rb_rs;
} }
RETURN_ENUMERATOR(str, argc, argv);
if (NIL_P(rs)) { if (NIL_P(rs)) {
rb_yield(str); rb_yield(str);
return str; return str;
@ -3751,6 +3755,7 @@ rb_str_each_byte(str)
{ {
long i; long i;
RETURN_ENUMERATOR(str, 0, 0);
for (i=0; i<RSTRING(str)->len; i++) { for (i=0; i<RSTRING(str)->len; i++) {
rb_yield(INT2FIX(RSTRING(str)->ptr[i] & 0xff)); rb_yield(INT2FIX(RSTRING(str)->ptr[i] & 0xff));
} }
@ -4267,6 +4272,8 @@ rb_str_scan(str, pat)
long start = 0; long start = 0;
VALUE match = Qnil; VALUE match = Qnil;
RETURN_ENUMERATOR(str, 1, &pat);
pat = get_pat(pat, 1); pat = get_pat(pat, 1);
if (!rb_block_given_p()) { if (!rb_block_given_p()) {
VALUE ary = rb_ary_new(); VALUE ary = rb_ary_new();

View File

@ -428,6 +428,7 @@ rb_struct_each(s)
{ {
long i; long i;
RETURN_ENUMERATOR(s, 0, 0);
for (i=0; i<RSTRUCT(s)->len; i++) { for (i=0; i<RSTRUCT(s)->len; i++) {
rb_yield(RSTRUCT(s)->ptr[i]); rb_yield(RSTRUCT(s)->ptr[i]);
} }
@ -459,6 +460,7 @@ rb_struct_each_pair(s)
VALUE members; VALUE members;
long i; long i;
RETURN_ENUMERATOR(s, 0, 0);
members = rb_struct_members(s); members = rb_struct_members(s);
for (i=0; i<RSTRUCT(s)->len; i++) { for (i=0; i<RSTRUCT(s)->len; i++) {
rb_yield_values(2, rb_ary_entry(members, i), RSTRUCT(s)->ptr[i]); rb_yield_values(2, rb_ary_entry(members, i), RSTRUCT(s)->ptr[i]);