mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* enum.c (enum_cycle): Make Enumerable#cycle do a finite loop when
the number of cycles is specified. * array.c (rb_ary_cycle): Ditto for Array#cycle. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@15991 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
31a060f7bd
commit
181f815591
3 changed files with 57 additions and 19 deletions
|
@ -1,3 +1,10 @@
|
||||||
|
Sun Apr 13 23:53:58 2008 Akinori MUSHA <knu@iDaemons.org>
|
||||||
|
|
||||||
|
* enum.c (enum_cycle): Make Enumerable#cycle do a finite loop when
|
||||||
|
the number of cycles is specified.
|
||||||
|
|
||||||
|
* array.c (rb_ary_cycle): Ditto for Array#cycle.
|
||||||
|
|
||||||
Sun Apr 13 18:52:27 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
Sun Apr 13 18:52:27 2008 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
* thread_pthread.c (lock_func): should not check interrupts in
|
* thread_pthread.c (lock_func): should not check interrupts in
|
||||||
|
|
34
array.c
34
array.c
|
@ -2938,24 +2938,40 @@ rb_ary_choice(VALUE ary)
|
||||||
/*
|
/*
|
||||||
* call-seq:
|
* call-seq:
|
||||||
* ary.cycle {|obj| block }
|
* ary.cycle {|obj| block }
|
||||||
|
* ary.cycle(n) {|obj| block }
|
||||||
*
|
*
|
||||||
* Calls <i>block</i> repeatedly forever.
|
* Calls <i>block</i> for each element repeatedly _n_ times or
|
||||||
|
* forever if none or nil is given. If a non-positive number is
|
||||||
|
* given or the array is empty, does nothing. Returns nil if the
|
||||||
|
* loop has finished without getting interrupted.
|
||||||
*
|
*
|
||||||
* a = ["a", "b", "c"]
|
* a = ["a", "b", "c"]
|
||||||
* a.cycle {|x| puts x } # print, a, b, c, a, b, c,.. forever.
|
* a.cycle {|x| puts x } # print, a, b, c, a, b, c,.. forever.
|
||||||
|
* a.cycle(2) {|x| puts x } # print, a, b, c, a, b, c.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
rb_ary_cycle(VALUE ary)
|
rb_ary_cycle(int argc, VALUE *argv, VALUE ary)
|
||||||
{
|
{
|
||||||
long i;
|
long n, i;
|
||||||
|
VALUE nv = Qnil;
|
||||||
|
|
||||||
RETURN_ENUMERATOR(ary, 0, 0);
|
rb_scan_args(argc, argv, "01", &nv);
|
||||||
while (RARRAY_LEN(ary) > 0) {
|
|
||||||
for (i=0; i<RARRAY_LEN(ary); i++) {
|
RETURN_ENUMERATOR(ary, argc, argv);
|
||||||
rb_yield(RARRAY_PTR(ary)[i]);
|
if (NIL_P(nv)) {
|
||||||
}
|
n = -1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
n = NUM2LONG(nv);
|
||||||
|
if (n <= 0) return Qnil;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (RARRAY_LEN(ary) > 0 && (n < 0 || 0 < n--)) {
|
||||||
|
for (i=0; i<RARRAY_LEN(ary); i++) {
|
||||||
|
rb_yield(RARRAY_PTR(ary)[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return Qnil;
|
return Qnil;
|
||||||
}
|
}
|
||||||
|
@ -3430,7 +3446,7 @@ Init_Array(void)
|
||||||
rb_define_method(rb_cArray, "shuffle!", rb_ary_shuffle_bang, 0);
|
rb_define_method(rb_cArray, "shuffle!", rb_ary_shuffle_bang, 0);
|
||||||
rb_define_method(rb_cArray, "shuffle", rb_ary_shuffle, 0);
|
rb_define_method(rb_cArray, "shuffle", rb_ary_shuffle, 0);
|
||||||
rb_define_method(rb_cArray, "choice", rb_ary_choice, 0);
|
rb_define_method(rb_cArray, "choice", rb_ary_choice, 0);
|
||||||
rb_define_method(rb_cArray, "cycle", rb_ary_cycle, 0);
|
rb_define_method(rb_cArray, "cycle", rb_ary_cycle, -1);
|
||||||
rb_define_method(rb_cArray, "permutation", rb_ary_permutation, -1);
|
rb_define_method(rb_cArray, "permutation", rb_ary_permutation, -1);
|
||||||
rb_define_method(rb_cArray, "combination", rb_ary_combination, 1);
|
rb_define_method(rb_cArray, "combination", rb_ary_combination, 1);
|
||||||
rb_define_method(rb_cArray, "product", rb_ary_product, -1);
|
rb_define_method(rb_cArray, "product", rb_ary_product, -1);
|
||||||
|
|
35
enum.c
35
enum.c
|
@ -1656,33 +1656,48 @@ cycle_i(VALUE i, VALUE ary, int argc, VALUE *argv)
|
||||||
/*
|
/*
|
||||||
* call-seq:
|
* call-seq:
|
||||||
* enum.cycle {|obj| block }
|
* enum.cycle {|obj| block }
|
||||||
|
* enum.cycle(n) {|obj| block }
|
||||||
*
|
*
|
||||||
* Calls <i>block</i> for each element of <i>enum</i> repeatedly
|
* Calls <i>block</i> for each element of <i>enum</i> repeatedly _n_
|
||||||
* forever. Returns nil if and only if the collection is empty.
|
* times or forever if none or nil is given. If a non-positive
|
||||||
|
* number is given or the collection is empty, does nothing. Returns
|
||||||
|
* nil if the loop has finished without getting interrupted.
|
||||||
|
*
|
||||||
* Enumerable#cycle saves elements in an internal array so changes
|
* Enumerable#cycle saves elements in an internal array so changes
|
||||||
* to <i>enum</i> after the first pass have no effect.
|
* to <i>enum</i> after the first pass have no effect.
|
||||||
*
|
*
|
||||||
* a = ["a", "b", "c"]
|
* a = ["a", "b", "c"]
|
||||||
* a.cycle {|x| puts x } # print, a, b, c, a, b, c,.. forever.
|
* a.cycle {|x| puts x } # print, a, b, c, a, b, c,.. forever.
|
||||||
|
* a.cycle(2) {|x| puts x } # print, a, b, c, a, b, c.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
enum_cycle(VALUE obj)
|
enum_cycle(int argc, VALUE *argv, VALUE obj)
|
||||||
{
|
{
|
||||||
VALUE ary;
|
VALUE ary;
|
||||||
long i, len;
|
VALUE nv = Qnil;
|
||||||
|
long n, i, len;
|
||||||
|
|
||||||
RETURN_ENUMERATOR(obj, 0, 0);
|
rb_scan_args(argc, argv, "01", &nv);
|
||||||
|
|
||||||
|
RETURN_ENUMERATOR(obj, argc, argv);
|
||||||
|
if (NIL_P(nv)) {
|
||||||
|
n = -1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
n = NUM2LONG(nv);
|
||||||
|
if (n <= 0) return Qnil;
|
||||||
|
}
|
||||||
ary = rb_ary_new();
|
ary = rb_ary_new();
|
||||||
RBASIC(ary)->klass = 0;
|
RBASIC(ary)->klass = 0;
|
||||||
rb_block_call(obj, id_each, 0, 0, cycle_i, ary);
|
rb_block_call(obj, id_each, 0, 0, cycle_i, ary);
|
||||||
len = RARRAY_LEN(ary);
|
len = RARRAY_LEN(ary);
|
||||||
if (len == 0) return Qnil;
|
if (len == 0) return Qnil;
|
||||||
for (;;) {
|
while (n < 0 || 0 < --n) {
|
||||||
for (i=0; i<len; i++) {
|
for (i=0; i<len; i++) {
|
||||||
rb_yield(RARRAY_PTR(ary)[i]);
|
rb_yield(RARRAY_PTR(ary)[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Qnil; /* not reached */
|
return Qnil; /* not reached */
|
||||||
}
|
}
|
||||||
|
@ -1741,7 +1756,7 @@ Init_Enumerable(void)
|
||||||
rb_define_method(rb_mEnumerable, "take_while", enum_take_while, 0);
|
rb_define_method(rb_mEnumerable, "take_while", enum_take_while, 0);
|
||||||
rb_define_method(rb_mEnumerable, "drop", enum_drop, 1);
|
rb_define_method(rb_mEnumerable, "drop", enum_drop, 1);
|
||||||
rb_define_method(rb_mEnumerable, "drop_while", enum_drop_while, 0);
|
rb_define_method(rb_mEnumerable, "drop_while", enum_drop_while, 0);
|
||||||
rb_define_method(rb_mEnumerable, "cycle", enum_cycle, 0);
|
rb_define_method(rb_mEnumerable, "cycle", enum_cycle, -1);
|
||||||
|
|
||||||
id_eqq = rb_intern("===");
|
id_eqq = rb_intern("===");
|
||||||
id_each = rb_intern("each");
|
id_each = rb_intern("each");
|
||||||
|
|
Loading…
Add table
Reference in a new issue