summaryrefslogtreecommitdiff
path: root/range.c
diff options
context:
space:
mode:
authormatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2002-05-01 09:41:50 +0000
committermatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2002-05-01 09:41:50 +0000
commit4fa0cdea7838a12afac492ee58af7f30660c6a8f (patch)
tree30895168554835060498505a41c9f5e72c4cddea /range.c
parentca55fe4f0d1477f9b2b14793468c370ebbb96ea7 (diff)
* numeric.c (num_step): better iteration condition for float
values; suggested by Masahiro TANAKA <masa@ir.isas.ac.jp>. * range.c (range_step): step (for Range#step method) <= 0 makes no sence, thus ArgError will be raised. * range.c (range_each): Range#each method is special case for Range#step(1) * file.c (rb_find_file): load must be done from an abolute path if $SAFE >= 4. * enum.c (enum_partition): new method. [new] * re.c (rb_reg_s_quote): quote whitespaces for /x cases. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@2420 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'range.c')
-rw-r--r--range.c111
1 files changed, 45 insertions, 66 deletions
diff --git a/range.c b/range.c
index 109dd72..8a92eac 100644
--- a/range.c
+++ b/range.c
@@ -75,7 +75,7 @@ range_initialize(argc, argv, obj)
rb_scan_args(argc, argv, "21", &beg, &end, &flags);
/* Ranges are immutable, so that they should be initialized only once. */
if (rb_ivar_defined(obj, id_beg)) {
- rb_name_error(rb_intern("initialized"), "`initialize' called twice");
+ rb_name_error(rb_intern("initialize"), "`initialize' called twice");
}
range_init(obj, beg, end, RTEST(flags));
return Qnil;
@@ -231,59 +231,6 @@ range_hash(range, obj)
}
static VALUE
-range_each(range)
- VALUE range;
-{
- VALUE b, e;
-
- b = rb_ivar_get(range, id_beg);
- e = rb_ivar_get(range, id_end);
-
- if (FIXNUM_P(b) && FIXNUM_P(e)) { /* fixnums are special */
- long end = FIX2LONG(e);
- long i;
-
- if (!EXCL(range)) end += 1;
- for (i=FIX2LONG(b); i<end; i++) {
- rb_yield(INT2NUM(i));
- }
- }
- else if (TYPE(b) == T_STRING) {
- rb_str_upto(b, e, EXCL(range));
- }
- else if (rb_obj_is_kind_of(b, rb_cNumeric)) {
- b = rb_Integer(b);
- e = rb_Integer(e);
-
- if (!EXCL(range)) e = rb_funcall(e, '+', 1, INT2FIX(1));
- while (RTEST(rb_funcall(b, '<', 1, e))) {
- rb_yield(b);
- b = rb_funcall(b, '+', 1, INT2FIX(1));
- }
- }
- else { /* generic each */
- VALUE v = b;
-
- if (EXCL(range)) {
- while (r_lt(v, e)) {
- if (r_eq(v, e)) break;
- rb_yield(v);
- v = rb_funcall(v, id_succ, 0, 0);
- }
- }
- else {
- while (r_le(v, e)) {
- rb_yield(v);
- if (r_eq(v, e)) break;
- v = rb_funcall(v, id_succ, 0, 0);
- }
- }
- }
-
- return range;
-}
-
-static VALUE
r_step_str(args)
VALUE *args;
{
@@ -313,26 +260,52 @@ range_step(argc, argv, range)
b = rb_ivar_get(range, id_beg);
e = rb_ivar_get(range, id_end);
- rb_scan_args(argc, argv, "01", &step);
+ if (rb_scan_args(argc, argv, "01", &step) == 0) {
+ step = INT2FIX(1);
+ }
if (FIXNUM_P(b) && FIXNUM_P(e)) { /* fixnums are special */
- long end = FIX2LONG(e);
- long i, s = (argc == 0) ? 1 : NUM2LONG(step);
-
- if (!EXCL(range)) end += 1;
- for (i=FIX2LONG(b); i<end; i+=s) {
- rb_yield(INT2NUM(i));
+ long beg = FIX2LONG(b), end = FIX2LONG(e), s = NUM2LONG(step);
+ long i;
+ if (s <= 0) {
+ rb_raise(rb_eArgError, "step can't be <= 0");
+ }
+ if ((end - beg) < 0) {
+ if (!EXCL(range)) end -= 1;
+ for (i=beg; i>end; i-=s) {
+ rb_yield(LONG2NUM(i));
+ }
+ }
+ else {
+ if (!EXCL(range)) end += 1;
+ for (i=beg; i<end; i+=s) {
+ rb_yield(INT2NUM(i));
+ }
}
}
else if (rb_obj_is_kind_of(b, rb_cNumeric)) {
+ VALUE diff;
b = rb_Integer(b);
e = rb_Integer(e);
step = rb_Integer(step);
- if (!EXCL(range)) e = rb_funcall(e, '+', 1, INT2FIX(1));
- while (RTEST(rb_funcall(b, '<', 1, e))) {
- rb_yield(b);
- b = rb_funcall(b, '+', 1, step);
+ if (RTEST(rb_funcall(step, rb_intern("<="), 1, INT2FIX(0)))) {
+ rb_raise(rb_eArgError, "step can't be <= 0");
+ }
+ diff = rb_funcall(e, '-', 1, b);
+ if (RTEST(rb_funcall(diff, '<', 1, INT2FIX(0)))) {
+ if (!EXCL(range)) e = rb_funcall(e, '-', 1, INT2FIX(1));
+ while (RTEST(rb_funcall(b, '>', 1, e))) {
+ rb_yield(b);
+ b = rb_funcall(b, '-', 1, step);
+ }
+ }
+ else {
+ if (!EXCL(range)) e = rb_funcall(e, '+', 1, INT2FIX(1));
+ while (RTEST(rb_funcall(b, '<', 1, e))) {
+ rb_yield(b);
+ b = rb_funcall(b, '+', 1, step);
+ }
}
}
else if (TYPE(b) == T_STRING) {
@@ -366,11 +339,17 @@ range_step(argc, argv, range)
}
}
}
-
return range;
}
static VALUE
+range_each(range)
+ VALUE range;
+{
+ return range_step(0, NULL, range);
+}
+
+static VALUE
range_first(obj)
VALUE obj;
{