summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog7
-rw-r--r--array.c14
-rw-r--r--dir.c1
-rw-r--r--enum.c28
-rw-r--r--hash.c13
-rw-r--r--intern.h5
-rw-r--r--io.c14
-rw-r--r--range.c4
-rw-r--r--string.c17
-rw-r--r--struct.c2
10 files changed, 73 insertions, 32 deletions
diff --git a/ChangeLog b/ChangeLog
index 45710b1920..f5482d382e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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.
diff --git a/array.c b/array.c
index cdb64bf4d8..b0aa738adb 100644
--- a/array.c
+++ b/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;
diff --git a/dir.c b/dir.c
index ddb2bf8055..e2991cac52 100644
--- a/dir.c
+++ b/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)) {
diff --git a/enum.c b/enum.c
index 1f9a15f2d0..c0c08e9808 100644
--- a/enum.c
+++ b/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;
diff --git a/hash.c b/hash.c
index f221418b60..7eb12ce286 100644
--- a/hash.c
+++ b/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);
diff --git a/intern.h b/intern.h
index 338eacd039..70e243629d 100644
--- a/intern.h
+++ b/intern.h
@@ -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));
diff --git a/io.c b/io.c
index 0a66f4bb43..c1081a7464 100644
--- a/io.c
+++ b/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);
}
diff --git a/range.c b/range.c
index 0eb79867bf..c146982a6c 100644
--- a/range.c
+++ b/range.c
@@ -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);
diff --git a/string.c b/string.c
index bbdafd0d25..16c1f02b1b 100644
--- a/string.c
+++ b/string.c
@@ -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();
diff --git a/struct.c b/struct.c
index f6d825a01e..caae4a28bb 100644
--- a/struct.c
+++ b/struct.c
@@ -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]);