1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

* range.c (range_step): iteration done using "+" if elements are

Numeric.  Otherwise using "succ".

* range.c (range_each): iteration done using "succ".  If the
  elements does not respond to "succ", raise TypeError.  As a
  result, all Enumerable methods, e.g. collect, require elements
  to respond to "succ'.

* range.c (range_member): comparison done using "each", if
  elements are non-Numeric or no-"succ" objects.  Otherwise
  compare using "<=>".

* range.c (Init_Range): remove "size" and "length".


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@2506 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
matz 2002-05-30 06:12:29 +00:00
parent 21b2953030
commit 34f5c4061c
5 changed files with 118 additions and 184 deletions

View file

@ -1,3 +1,19 @@
Thu May 30 12:52:42 2002 Yukihiro Matsumoto <matz@ruby-lang.org>
* range.c (range_step): iteration done using "+" if elements are
Numeric. Otherwise using "succ".
* range.c (range_each): iteration done using "succ". If the
elements does not respond to "succ", raise TypeError. As a
result, all Enumerable methods, e.g. collect, require elements
to respond to "succ'.
* range.c (range_member): comparison done using "each", if
elements are non-Numeric or no-"succ" objects. Otherwise
compare using "<=>".
* range.c (Init_Range): remove "size" and "length".
Thu May 30 09:16:36 2002 Wakou Aoyama <wakou@ruby-lang.org> Thu May 30 09:16:36 2002 Wakou Aoyama <wakou@ruby-lang.org>
* lib/cgi.rb: if StringIO is usable then use it. * lib/cgi.rb: if StringIO is usable then use it.
@ -46,10 +62,6 @@ Tue May 28 12:13:37 2002 Nobuyoshi Nakada <nobu.nokada@softhome.net>
* node.h (NEW_DASGN, NEW_DASGN_CURR): remove surplus semicolons. * node.h (NEW_DASGN, NEW_DASGN_CURR): remove surplus semicolons.
Mon May 27 04:31:37 2002 Yukihiro Matsumoto <matz@ruby-lang.org>
* time.c (time_succ): new method for Range support.
Fri May 24 09:06:29 2002 Yukihiro Matsumoto <matz@ruby-lang.org> Fri May 24 09:06:29 2002 Yukihiro Matsumoto <matz@ruby-lang.org>
* time.c (time_arg): nil test against v[6] (usec). * time.c (time_arg): nil test against v[6] (usec).

2
eval.c
View file

@ -3851,7 +3851,7 @@ rb_yield_0(val, self, klass, pcall)
if (ruby_dyna_vars->id == 0) { if (ruby_dyna_vars->id == 0) {
vars = ruby_dyna_vars->next; vars = ruby_dyna_vars->next;
rb_gc_force_recycle((VALUE)ruby_dyna_vars); rb_gc_force_recycle((VALUE)ruby_dyna_vars);
while (vars && vars->id != 0) { while (vars && vars->id != 0 && vars != block->dyna_vars) {
struct RVarmap *tmp = vars->next; struct RVarmap *tmp = vars->next;
rb_gc_force_recycle((VALUE)vars); rb_gc_force_recycle((VALUE)vars);
vars = tmp; vars = tmp;

View file

@ -363,9 +363,10 @@ module Math
alias sin! sin alias sin! sin
alias tan! tan alias tan! tan
alias log! log alias log! log
alias atan! atan
alias log10! log10 alias log10! log10
alias atan2! atan2 alias atan2! atan2
def sqrt(z) def sqrt(z)
if Complex.generic?(z) if Complex.generic?(z)
if z >= 0 if z >= 0

265
range.c
View file

@ -146,58 +146,6 @@ r_gt(a,b)
return Qfalse; return Qfalse;
} }
static VALUE
r_eqq_str_i(i, data)
VALUE i;
VALUE *data;
{
if (rb_str_cmp(i, data[0]) == 0) {
data[1] = Qtrue;
rb_iter_break();
}
return Qnil;
}
static VALUE
range_eqq(range, obj)
VALUE range, obj;
{
VALUE beg, end;
beg = rb_ivar_get(range, id_beg);
end = rb_ivar_get(range, id_end);
if (FIXNUM_P(beg) && FIXNUM_P(obj) && FIXNUM_P(end)) {
if (FIX2LONG(beg) <= FIX2LONG(obj)) {
if (EXCL(range)) {
if (FIX2LONG(obj) < FIX2LONG(end)) return Qtrue;
}
else {
if (FIX2LONG(obj) <= FIX2LONG(end)) return Qtrue;
}
}
return Qfalse;
}
else if (TYPE(beg) == T_STRING &&
TYPE(obj) == T_STRING &&
TYPE(end) == T_STRING) {
VALUE data[2];
data[0] = obj; data[1] = Qfalse;
rb_iterate(rb_each, range, r_eqq_str_i, (VALUE)data);
return data[1];
}
else if (r_le(beg, obj)) {
if (EXCL(range)) {
if (r_lt(obj, end)) return Qtrue;
}
else {
if (r_le(obj, end)) return Qtrue;
}
}
return Qfalse;
}
static VALUE static VALUE
range_eql(range, obj) range_eql(range, obj)
VALUE range, obj; VALUE range, obj;
@ -216,8 +164,8 @@ range_eql(range, obj)
} }
static VALUE static VALUE
range_hash(range, obj) range_hash(range)
VALUE range, obj; VALUE range;
{ {
long hash = EXCL(range); long hash = EXCL(range);
VALUE v; VALUE v;
@ -226,19 +174,20 @@ range_hash(range, obj)
hash ^= v << 1; hash ^= v << 1;
v = rb_hash(rb_ivar_get(range, id_end)); v = rb_hash(rb_ivar_get(range, id_end));
hash ^= v << 9; hash ^= v << 9;
hash ^= EXCL(range) << 24;
return INT2FIX(hash); return INT2FIX(hash);
} }
static VALUE static VALUE
r_step_str(args) str_step(args)
VALUE *args; VALUE *args;
{ {
return rb_str_upto(args[0], args[1], EXCL(args[2])); return rb_str_upto(args[0], args[1], EXCL(args[2]));
} }
static VALUE static VALUE
r_step_str_i(i, iter) step_i(i, iter)
VALUE i; VALUE i;
long *iter; long *iter;
{ {
@ -250,6 +199,28 @@ r_step_str_i(i, iter)
return Qnil; return Qnil;
} }
static void
range_each_func(range, func, v, e, arg)
VALUE range;
void (*func) _((VALUE, void*));
void *arg;
{
if (EXCL(range)) {
while (r_lt(v, e)) {
if (r_eq(v, e)) break;
(*func)(v, arg);
v = rb_funcall(v, id_succ, 0, 0);
}
}
else {
while (r_le(v, e)) {
(*func)(v, arg);
if (r_eq(v, e)) break;
v = rb_funcall(v, id_succ, 0, 0);
}
}
}
static VALUE static VALUE
range_step(argc, argv, range) range_step(argc, argv, range)
int argc; int argc;
@ -257,6 +228,7 @@ range_step(argc, argv, range)
VALUE range; VALUE range;
{ {
VALUE b, e, step; VALUE b, e, step;
long unit;
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);
@ -264,27 +236,23 @@ range_step(argc, argv, range)
step = INT2FIX(1); step = INT2FIX(1);
} }
unit = NUM2LONG(step);
if (unit <= 0) {
rb_raise(rb_eArgError, "step can't be <= 0");
}
if (FIXNUM_P(b) && FIXNUM_P(e)) { /* fixnums are special */ if (FIXNUM_P(b) && FIXNUM_P(e)) { /* fixnums are special */
long end = FIX2LONG(e), s = NUM2LONG(step); long end = FIX2LONG(e);
long i; long i;
if (s <= 0) {
rb_raise(rb_eArgError, "step can't be <= 0");
}
if (!EXCL(range)) end += 1; if (!EXCL(range)) end += 1;
for (i=FIX2LONG(b); i<end; i+=s) { for (i=FIX2LONG(b); i<end; i+=unit) {
rb_yield(INT2NUM(i)); rb_yield(INT2NUM(i));
} }
} }
else if (rb_obj_is_kind_of(b, rb_cNumeric)) { else if (rb_obj_is_kind_of(b, rb_cNumeric)) {
b = rb_Integer(b); ID c = rb_intern(EXCL(range) ? "<" : "<=");
e = rb_Integer(e);
step = rb_Integer(step);
if (RTEST(rb_funcall(step, rb_intern("<="), 1, INT2FIX(0)))) { while (RTEST(rb_funcall(b, c, 1, e))) {
rb_raise(rb_eArgError, "step can't be <= 0");
}
if (!EXCL(range)) e = rb_funcall(e, '+', 1, INT2FIX(1));
while (RTEST(rb_funcall(b, '<', 1, e))) {
rb_yield(b); rb_yield(b);
b = rb_funcall(b, '+', 1, step); b = rb_funcall(b, '+', 1, step);
} }
@ -294,66 +262,70 @@ range_step(argc, argv, range)
long iter[2]; long iter[2];
args[0] = b; args[1] = e; args[2] = range; args[0] = b; args[1] = e; args[2] = range;
iter[0] = 1; iter[1] = NUM2LONG(step); iter[0] = 1; iter[1] = unit;
if (iter[1] <= 0) { rb_iterate((VALUE(*)_((VALUE)))str_step, (VALUE)args, step_i, (VALUE)iter);
rb_raise(rb_eArgError, "step can't be <= 0");
}
rb_iterate((VALUE(*)_((VALUE)))r_step_str, (VALUE)args, r_step_str_i,
(VALUE)iter);
} }
else { /* generic each */ else {
VALUE v = b; long args[2];
long lim = NUM2LONG(step);
long i;
if (lim <= 0) { if (!rb_respond_to(b, id_succ)) {
rb_raise(rb_eArgError, "step can't be <= 0"); rb_raise(rb_eTypeError, "cannot iterate from %s",
} rb_class2name(CLASS_OF(b)));
if (EXCL(range)) {
while (r_lt(v, e)) {
if (r_eq(v, e)) break;
rb_yield(v);
for (i=0; i<lim; i++)
v = rb_funcall(v, id_succ, 0, 0);
}
}
else {
while (r_le(v, e)) {
rb_yield(v);
if (r_eq(v, e)) break;
for (i=0; i<lim; i++)
v = rb_funcall(v, id_succ, 0, 0);
}
} }
args[0] = 1;
args[1] = unit;
range_each_func(range, step_i, b, e, args);
} }
return range; return range;
} }
static void
each_i(v, arg)
VALUE v;
void *arg;
{
rb_yield(v);
}
static VALUE static VALUE
range_each(range) range_each(range)
VALUE range; VALUE range;
{ {
return range_step(0, NULL, range); VALUE beg, end;
beg = rb_ivar_get(range, id_beg);
end = rb_ivar_get(range, id_end);
if (!rb_respond_to(beg, id_succ)) {
rb_raise(rb_eTypeError, "cannot iterate from %s",
rb_class2name(CLASS_OF(beg)));
}
if (TYPE(beg) == T_STRING) {
VALUE args[5];
long iter[2];
args[0] = beg; args[1] = end; args[2] = range;
iter[0] = 1; iter[1] = 1;
rb_iterate((VALUE(*)_((VALUE)))str_step, (VALUE)args, step_i, (VALUE)iter);
}
else {
range_each_func(range, each_i, beg, end, 0);
}
return range;
} }
static VALUE static VALUE
range_first(obj) range_first(obj)
VALUE obj; VALUE obj;
{ {
VALUE b; return rb_ivar_get(obj, id_beg);
b = rb_ivar_get(obj, id_beg);
return b;
} }
static VALUE static VALUE
range_last(obj) range_last(obj)
VALUE obj; VALUE obj;
{ {
VALUE e; return rb_ivar_get(obj, id_end);
e = rb_ivar_get(obj, id_end);
return e;
} }
VALUE VALUE
@ -439,58 +411,14 @@ range_inspect(range)
return str; return str;
} }
static VALUE static void
length_i(i, length) member_i(v, args)
VALUE i; VALUE v;
int *length; VALUE *args;
{ {
(*length)++; if (rb_equal(v, args[0])) {
return Qnil; args[1] = Qtrue;
}
VALUE
rb_length_by_each(obj)
VALUE obj;
{
int length = 0;
rb_iterate(rb_each, obj, length_i, (VALUE)&length);
return INT2FIX(length);
}
static VALUE
range_length(range)
VALUE range;
{
VALUE beg, end;
long size;
beg = rb_ivar_get(range, id_beg);
end = rb_ivar_get(range, id_end);
if (r_gt(beg, end)) {
return INT2FIX(0);
} }
if (FIXNUM_P(beg) && FIXNUM_P(end)) {
if (EXCL(range)) {
return INT2NUM(NUM2LONG(end) - NUM2LONG(beg));
}
else {
return INT2NUM(NUM2LONG(end) - NUM2LONG(beg) + 1);
}
}
if (!rb_obj_is_kind_of(beg, rb_cInteger)) {
return rb_length_by_each(range);
}
size = rb_funcall(end, '-', 1, beg);
if (!EXCL(range)) {
size = rb_funcall(size, '+', 1, INT2FIX(1));
}
if (TYPE(size) == T_FLOAT) {
size = rb_funcall(size, rb_intern("floor"), 0);
}
return size;
} }
static VALUE static VALUE
@ -498,18 +426,25 @@ range_member(range, val)
VALUE range, val; VALUE range, val;
{ {
VALUE beg, end; VALUE beg, end;
VALUE args[2];
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);
if (r_gt(beg, val)) return Qfalse; if (rb_obj_is_kind_of(beg, rb_cNumeric) || !rb_respond_to(beg, id_succ)) {
if (EXCL(range)) { if (r_gt(beg, val)) return Qfalse;
if (r_lt(val, end)) return Qtrue; if (EXCL(range)) {
if (r_lt(val, end)) return Qtrue;
}
else {
if (r_le(val, end)) return Qtrue;
}
return Qfalse;
} }
else { args[0] = val;
if (r_le(val, end)) return Qtrue; args[1] = Qfalse;
} range_each_func(range, member_i, beg, end, args);
return Qfalse; return args[1];
} }
void void
@ -519,7 +454,7 @@ Init_Range()
rb_include_module(rb_cRange, rb_mEnumerable); rb_include_module(rb_cRange, rb_mEnumerable);
rb_define_method(rb_cRange, "initialize", range_initialize, -1); rb_define_method(rb_cRange, "initialize", range_initialize, -1);
rb_define_method(rb_cRange, "==", range_eq, 1); rb_define_method(rb_cRange, "==", range_eq, 1);
rb_define_method(rb_cRange, "===", range_eqq, 1); rb_define_method(rb_cRange, "===", range_member, 1);
rb_define_method(rb_cRange, "eql?", range_eql, 1); rb_define_method(rb_cRange, "eql?", range_eql, 1);
rb_define_method(rb_cRange, "hash", range_hash, 0); rb_define_method(rb_cRange, "hash", range_hash, 0);
rb_define_method(rb_cRange, "each", range_each, 0); rb_define_method(rb_cRange, "each", range_each, 0);
@ -534,8 +469,6 @@ Init_Range()
rb_define_method(rb_cRange, "exclude_end?", range_exclude_end_p, 0); rb_define_method(rb_cRange, "exclude_end?", range_exclude_end_p, 0);
rb_define_method(rb_cRange, "length", range_length, 0);
rb_define_method(rb_cRange, "size", range_length, 0);
rb_define_method(rb_cRange, "member?", range_member, 1); rb_define_method(rb_cRange, "member?", range_member, 1);
rb_define_method(rb_cRange, "include?", range_member, 1); rb_define_method(rb_cRange, "include?", range_member, 1);

12
time.c
View file

@ -690,16 +690,6 @@ time_usec(time)
return INT2NUM(tobj->tv.tv_usec); return INT2NUM(tobj->tv.tv_usec);
} }
static VALUE
time_succ(time)
VALUE time;
{
struct time_object *tobj;
GetTimeval(time, tobj);
return rb_time_new(tobj->tv.tv_sec + 1, tobj->tv.tv_usec);
}
static VALUE static VALUE
time_cmp(time1, time2) time_cmp(time1, time2)
VALUE time1, time2; VALUE time1, time2;
@ -1449,8 +1439,6 @@ Init_Time()
rb_define_method(rb_cTime, "hash", time_hash, 0); rb_define_method(rb_cTime, "hash", time_hash, 0);
rb_define_method(rb_cTime, "clone", time_clone, 0); rb_define_method(rb_cTime, "clone", time_clone, 0);
rb_define_method(rb_cTime, "dup", time_dup, 0); rb_define_method(rb_cTime, "dup", time_dup, 0);
rb_define_method(rb_cTime, "succ", time_succ, 0);
rb_define_method(rb_cTime, "next", time_succ, 0);
rb_define_method(rb_cTime, "localtime", time_localtime, 0); rb_define_method(rb_cTime, "localtime", time_localtime, 0);
rb_define_method(rb_cTime, "gmtime", time_gmtime, 0); rb_define_method(rb_cTime, "gmtime", time_gmtime, 0);