зеркало из https://github.com/github/ruby.git
* 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:
Родитель
21b2953030
Коммит
34f5c4061c
20
ChangeLog
20
ChangeLog
|
@ -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>
|
||||
|
||||
* 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.
|
||||
|
||||
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>
|
||||
|
||||
* time.c (time_arg): nil test against v[6] (usec).
|
||||
|
|
2
eval.c
2
eval.c
|
@ -3851,7 +3851,7 @@ rb_yield_0(val, self, klass, pcall)
|
|||
if (ruby_dyna_vars->id == 0) {
|
||||
vars = ruby_dyna_vars->next;
|
||||
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;
|
||||
rb_gc_force_recycle((VALUE)vars);
|
||||
vars = tmp;
|
||||
|
|
|
@ -363,9 +363,10 @@ module Math
|
|||
alias sin! sin
|
||||
alias tan! tan
|
||||
alias log! log
|
||||
alias atan! atan
|
||||
alias log10! log10
|
||||
alias atan2! atan2
|
||||
|
||||
|
||||
def sqrt(z)
|
||||
if Complex.generic?(z)
|
||||
if z >= 0
|
||||
|
|
265
range.c
265
range.c
|
@ -146,58 +146,6 @@ r_gt(a,b)
|
|||
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
|
||||
range_eql(range, obj)
|
||||
VALUE range, obj;
|
||||
|
@ -216,8 +164,8 @@ range_eql(range, obj)
|
|||
}
|
||||
|
||||
static VALUE
|
||||
range_hash(range, obj)
|
||||
VALUE range, obj;
|
||||
range_hash(range)
|
||||
VALUE range;
|
||||
{
|
||||
long hash = EXCL(range);
|
||||
VALUE v;
|
||||
|
@ -226,19 +174,20 @@ range_hash(range, obj)
|
|||
hash ^= v << 1;
|
||||
v = rb_hash(rb_ivar_get(range, id_end));
|
||||
hash ^= v << 9;
|
||||
hash ^= EXCL(range) << 24;
|
||||
|
||||
return INT2FIX(hash);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
r_step_str(args)
|
||||
str_step(args)
|
||||
VALUE *args;
|
||||
{
|
||||
return rb_str_upto(args[0], args[1], EXCL(args[2]));
|
||||
}
|
||||
|
||||
static VALUE
|
||||
r_step_str_i(i, iter)
|
||||
step_i(i, iter)
|
||||
VALUE i;
|
||||
long *iter;
|
||||
{
|
||||
|
@ -250,6 +199,28 @@ r_step_str_i(i, iter)
|
|||
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
|
||||
range_step(argc, argv, range)
|
||||
int argc;
|
||||
|
@ -257,6 +228,7 @@ range_step(argc, argv, range)
|
|||
VALUE range;
|
||||
{
|
||||
VALUE b, e, step;
|
||||
long unit;
|
||||
|
||||
b = rb_ivar_get(range, id_beg);
|
||||
e = rb_ivar_get(range, id_end);
|
||||
|
@ -264,27 +236,23 @@ range_step(argc, argv, range)
|
|||
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 */
|
||||
long end = FIX2LONG(e), s = NUM2LONG(step);
|
||||
long end = FIX2LONG(e);
|
||||
long i;
|
||||
if (s <= 0) {
|
||||
rb_raise(rb_eArgError, "step can't be <= 0");
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
else if (rb_obj_is_kind_of(b, rb_cNumeric)) {
|
||||
b = rb_Integer(b);
|
||||
e = rb_Integer(e);
|
||||
step = rb_Integer(step);
|
||||
ID c = rb_intern(EXCL(range) ? "<" : "<=");
|
||||
|
||||
if (RTEST(rb_funcall(step, rb_intern("<="), 1, INT2FIX(0)))) {
|
||||
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))) {
|
||||
while (RTEST(rb_funcall(b, c, 1, e))) {
|
||||
rb_yield(b);
|
||||
b = rb_funcall(b, '+', 1, step);
|
||||
}
|
||||
|
@ -294,66 +262,70 @@ range_step(argc, argv, range)
|
|||
long iter[2];
|
||||
|
||||
args[0] = b; args[1] = e; args[2] = range;
|
||||
iter[0] = 1; iter[1] = NUM2LONG(step);
|
||||
if (iter[1] <= 0) {
|
||||
rb_raise(rb_eArgError, "step can't be <= 0");
|
||||
}
|
||||
rb_iterate((VALUE(*)_((VALUE)))r_step_str, (VALUE)args, r_step_str_i,
|
||||
(VALUE)iter);
|
||||
iter[0] = 1; iter[1] = unit;
|
||||
rb_iterate((VALUE(*)_((VALUE)))str_step, (VALUE)args, step_i, (VALUE)iter);
|
||||
}
|
||||
else { /* generic each */
|
||||
VALUE v = b;
|
||||
long lim = NUM2LONG(step);
|
||||
long i;
|
||||
else {
|
||||
long args[2];
|
||||
|
||||
if (lim <= 0) {
|
||||
rb_raise(rb_eArgError, "step can't be <= 0");
|
||||
}
|
||||
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);
|
||||
}
|
||||
if (!rb_respond_to(b, id_succ)) {
|
||||
rb_raise(rb_eTypeError, "cannot iterate from %s",
|
||||
rb_class2name(CLASS_OF(b)));
|
||||
}
|
||||
args[0] = 1;
|
||||
args[1] = unit;
|
||||
range_each_func(range, step_i, b, e, args);
|
||||
}
|
||||
return range;
|
||||
}
|
||||
|
||||
static void
|
||||
each_i(v, arg)
|
||||
VALUE v;
|
||||
void *arg;
|
||||
{
|
||||
rb_yield(v);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
range_each(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
|
||||
range_first(obj)
|
||||
VALUE obj;
|
||||
{
|
||||
VALUE b;
|
||||
|
||||
b = rb_ivar_get(obj, id_beg);
|
||||
return b;
|
||||
return rb_ivar_get(obj, id_beg);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
range_last(obj)
|
||||
VALUE obj;
|
||||
{
|
||||
VALUE e;
|
||||
|
||||
e = rb_ivar_get(obj, id_end);
|
||||
return e;
|
||||
return rb_ivar_get(obj, id_end);
|
||||
}
|
||||
|
||||
VALUE
|
||||
|
@ -439,58 +411,14 @@ range_inspect(range)
|
|||
return str;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
length_i(i, length)
|
||||
VALUE i;
|
||||
int *length;
|
||||
static void
|
||||
member_i(v, args)
|
||||
VALUE v;
|
||||
VALUE *args;
|
||||
{
|
||||
(*length)++;
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
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 (rb_equal(v, args[0])) {
|
||||
args[1] = Qtrue;
|
||||
}
|
||||
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
|
||||
|
@ -498,18 +426,25 @@ range_member(range, val)
|
|||
VALUE range, val;
|
||||
{
|
||||
VALUE beg, end;
|
||||
VALUE args[2];
|
||||
|
||||
beg = rb_ivar_get(range, id_beg);
|
||||
end = rb_ivar_get(range, id_end);
|
||||
|
||||
if (r_gt(beg, val)) return Qfalse;
|
||||
if (EXCL(range)) {
|
||||
if (r_lt(val, end)) return Qtrue;
|
||||
if (rb_obj_is_kind_of(beg, rb_cNumeric) || !rb_respond_to(beg, id_succ)) {
|
||||
if (r_gt(beg, val)) return Qfalse;
|
||||
if (EXCL(range)) {
|
||||
if (r_lt(val, end)) return Qtrue;
|
||||
}
|
||||
else {
|
||||
if (r_le(val, end)) return Qtrue;
|
||||
}
|
||||
return Qfalse;
|
||||
}
|
||||
else {
|
||||
if (r_le(val, end)) return Qtrue;
|
||||
}
|
||||
return Qfalse;
|
||||
args[0] = val;
|
||||
args[1] = Qfalse;
|
||||
range_each_func(range, member_i, beg, end, args);
|
||||
return args[1];
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -519,7 +454,7 @@ Init_Range()
|
|||
rb_include_module(rb_cRange, rb_mEnumerable);
|
||||
rb_define_method(rb_cRange, "initialize", range_initialize, -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, "hash", range_hash, 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, "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, "include?", range_member, 1);
|
||||
|
||||
|
|
12
time.c
12
time.c
|
@ -690,16 +690,6 @@ time_usec(time)
|
|||
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
|
||||
time_cmp(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, "clone", time_clone, 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, "gmtime", time_gmtime, 0);
|
||||
|
|
Загрузка…
Ссылка в новой задаче