* 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
Родитель 87e8b14cc4
Коммит 74433fd300
10 изменённых файлов: 73 добавлений и 32 удалений

Просмотреть файл

@ -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>
* lib/debug.rb: no need to restart at exit.

14
array.c
Просмотреть файл

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

1
dir.c
Просмотреть файл

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

28
enum.c
Просмотреть файл

@ -17,15 +17,6 @@
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)
VALUE obj;
@ -123,8 +114,7 @@ enum_find(argc, argv, obj)
VALUE if_none;
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) {
return memo;
@ -164,7 +154,7 @@ 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();
rb_iterate(rb_each, obj, find_all_i, ary);
@ -199,7 +189,7 @@ enum_reject(obj)
{
VALUE ary;
if (!rb_block_given_p()) return enumeratorize(0, 0, obj);
RETURN_ENUMERATOR(obj, 0, 0);
ary = rb_ary_new();
rb_iterate(rb_each, obj, reject_i, ary);
@ -244,7 +234,7 @@ enum_collect(obj)
{
VALUE ary;
if (!rb_block_given_p()) return enumeratorize(0, 0, obj);
RETURN_ENUMERATOR(obj, 0, 0);
ary = rb_ary_new();
rb_iterate(rb_each, obj, collect_i, ary);
@ -363,7 +353,7 @@ 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();
ary[1] = rb_ary_new();
@ -498,7 +488,7 @@ enum_sort_by(obj)
VALUE ary;
long i;
if (!rb_block_given_p()) return enumeratorize(0, 0, obj);
RETURN_ENUMERATOR(obj, 0, 0);
if (TYPE(obj) == T_ARRAY) {
ary = rb_ary_new2(RARRAY(obj)->len);
@ -787,7 +777,7 @@ 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;
memo[1] = Qnil;
@ -831,7 +821,7 @@ 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;
memo[1] = Qnil;
@ -907,7 +897,7 @@ 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);
return obj;

13
hash.c
Просмотреть файл

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

Просмотреть файл

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

14
io.c
Просмотреть файл

@ -1851,6 +1851,7 @@ rb_io_each_line(argc, argv, io)
VALUE str;
VALUE rs;
RETURN_ENUMERATOR(io, argc, argv);
if (argc == 0) {
rs = rb_rs;
}
@ -1885,6 +1886,7 @@ rb_io_each_byte(io)
OpenFile *fptr;
int c;
RETURN_ENUMERATOR(io, 0, 0);
GetOpenFile(io, fptr);
for (;;) {
@ -5153,13 +5155,15 @@ 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);
if (argc == 1) {
@ -5453,12 +5457,14 @@ 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) {
for (;;) {
@ -5474,10 +5480,12 @@ 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);
}

Просмотреть файл

@ -303,6 +303,8 @@ range_step(argc, argv, range)
VALUE b, e, step;
long unit;
RETURN_ENUMERATOR(range, argc, argv);
b = rb_ivar_get(range, id_beg);
e = rb_ivar_get(range, id_end);
if (rb_scan_args(argc, argv, "01", &step) == 0) {
@ -392,6 +394,8 @@ 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);

Просмотреть файл

@ -2048,15 +2048,17 @@ str_gsub(argc, argv, str, bang)
char *buf, *bp, *sp, *cp;
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);
}
@ -3692,6 +3694,8 @@ rb_str_each_line(argc, argv, str)
rs = rb_rs;
}
RETURN_ENUMERATOR(str, argc, argv);
if (NIL_P(rs)) {
rb_yield(str);
return str;
@ -3751,6 +3755,7 @@ 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));
}
@ -4267,6 +4272,8 @@ rb_str_scan(str, pat)
long start = 0;
VALUE match = Qnil;
RETURN_ENUMERATOR(str, 1, &pat);
pat = get_pat(pat, 1);
if (!rb_block_given_p()) {
VALUE ary = rb_ary_new();

Просмотреть файл

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