1 /**********************************************************************
6 created at: Fri Aug 6 09:46:12 JST 1993
8 Copyright (C) 1993-2007 Yukihiro Matsumoto
9 Copyright (C) 2000 Network Applied Communication Laboratory, Inc.
10 Copyright (C) 2000 Information-technology Promotion Agency, Japan
12 **********************************************************************/
14 #include "ruby/ruby.h"
15 #include "ruby/util.h"
22 #define ARY_DEFAULT_SIZE 16
23 #define ARY_MAX_SIZE (LONG_MAX / sizeof(VALUE))
26 rb_mem_clear(register VALUE
*mem
, register long size
)
34 memfill(register VALUE
*mem
, register long size
, register VALUE val
)
41 #define ARY_SHARED_P(a) FL_TEST(a, ELTS_SHARED)
43 #define ARY_SET_LEN(ary, n) do { \
44 RARRAY(ary)->len = (n);\
47 #define ARY_CAPA(ary) RARRAY(ary)->aux.capa
48 #define RESIZE_CAPA(ary,capacity) do {\
49 REALLOC_N(RARRAY(ary)->ptr, VALUE, (capacity));\
50 RARRAY(ary)->aux.capa = (capacity);\
54 rb_ary_modify_check(VALUE ary
)
56 if (OBJ_FROZEN(ary
)) rb_error_frozen("array");
57 if (!OBJ_UNTRUSTED(ary
) && rb_safe_level() >= 4)
58 rb_raise(rb_eSecurityError
, "Insecure: can't modify array");
62 rb_ary_modify(VALUE ary
)
66 rb_ary_modify_check(ary
);
67 if (ARY_SHARED_P(ary
)) {
68 ptr
= ALLOC_N(VALUE
, RARRAY_LEN(ary
));
69 FL_UNSET(ary
, ELTS_SHARED
);
70 RARRAY(ary
)->aux
.capa
= RARRAY_LEN(ary
);
71 MEMCPY(ptr
, RARRAY_PTR(ary
), VALUE
, RARRAY_LEN(ary
));
72 RARRAY(ary
)->ptr
= ptr
;
77 rb_ary_freeze(VALUE ary
)
79 return rb_obj_freeze(ary
);
84 * array.frozen? -> true or false
86 * Return <code>true</code> if this array is frozen (or temporarily frozen
87 * while being sorted).
91 rb_ary_frozen_p(VALUE ary
)
93 if (OBJ_FROZEN(ary
)) return Qtrue
;
98 ary_alloc(VALUE klass
)
100 NEWOBJ(ary
, struct RArray
);
101 OBJSETUP(ary
, klass
, T_ARRAY
);
111 ary_new(VALUE klass
, long len
)
116 rb_raise(rb_eArgError
, "negative array size (or size too big)");
118 if (len
> ARY_MAX_SIZE
) {
119 rb_raise(rb_eArgError
, "array size too big");
121 ary
= ary_alloc(klass
);
123 RARRAY(ary
)->ptr
= ALLOC_N(VALUE
, len
);
124 RARRAY(ary
)->aux
.capa
= len
;
130 rb_ary_new2(long len
)
132 return ary_new(rb_cArray
, len
);
139 return rb_ary_new2(ARY_DEFAULT_SIZE
);
145 rb_ary_new3(long n
, ...)
151 ary
= rb_ary_new2(n
);
154 for (i
=0; i
<n
; i
++) {
155 RARRAY_PTR(ary
)[i
] = va_arg(ar
, VALUE
);
159 RARRAY(ary
)->len
= n
;
164 rb_ary_new4(long n
, const VALUE
*elts
)
168 ary
= rb_ary_new2(n
);
170 MEMCPY(RARRAY_PTR(ary
), elts
, VALUE
, n
);
171 RARRAY(ary
)->len
= n
;
178 rb_ary_tmp_new(long len
)
180 return ary_new(0, len
);
184 rb_ary_free(VALUE ary
)
186 if (!ARY_SHARED_P(ary
)) {
187 xfree(RARRAY(ary
)->ptr
);
192 ary_make_shared(VALUE ary
)
194 if (ARY_SHARED_P(ary
)) {
195 return RARRAY(ary
)->aux
.shared
;
198 NEWOBJ(shared
, struct RArray
);
199 OBJSETUP(shared
, 0, T_ARRAY
);
201 shared
->len
= RARRAY(ary
)->len
;
202 shared
->ptr
= RARRAY(ary
)->ptr
;
203 shared
->aux
.capa
= RARRAY(ary
)->aux
.capa
;
204 RARRAY(ary
)->aux
.shared
= (VALUE
)shared
;
205 FL_SET(ary
, ELTS_SHARED
);
207 return (VALUE
)shared
;
212 rb_assoc_new(VALUE car
, VALUE cdr
)
214 return rb_ary_new3(2, car
, cdr
);
220 return rb_convert_type(ary
, T_ARRAY
, "Array", "to_ary");
224 rb_check_array_type(VALUE ary
)
226 return rb_check_convert_type(ary
, T_ARRAY
, "Array", "to_ary");
231 * Array.try_convert(obj) -> array or nil
233 * Try to convert <i>obj</i> into an array, using to_ary method.
234 * Returns converted array or nil if <i>obj</i> cannot be converted
235 * for any reason. This method is to check if an argument is an
238 * Array.try_convert([1]) # => [1]
239 * Array.try_convert("1") # => nil
241 * if tmp = Array.try_convert(arg)
242 * # the argument is an array
243 * elsif tmp = String.try_convert(arg)
244 * # the argument is a string
250 rb_ary_s_try_convert(VALUE dummy
, VALUE ary
)
252 return rb_check_array_type(ary
);
257 * Array.new(size=0, obj=nil)
259 * Array.new(size) {|index| block }
261 * Returns a new array. In the first form, the new array is
262 * empty. In the second it is created with _size_ copies of _obj_
263 * (that is, _size_ references to the same
264 * _obj_). The third form creates a copy of the array
265 * passed as a parameter (the array is generated by calling
266 * to_ary on the parameter). In the last form, an array
267 * of the given size is created. Each element in this array is
268 * calculated by passing the element's index to the given block and
269 * storing the return value.
275 * # only one copy of the object is created
276 * a = Array.new(2, Hash.new)
277 * a[0]['cat'] = 'feline'
279 * a[1]['cat'] = 'Felix'
282 * # here multiple copies are created
283 * a = Array.new(2) { Hash.new }
284 * a[0]['cat'] = 'feline'
287 * squares = Array.new(5) {|i| i*i}
290 * copy = Array.new(squares)
294 rb_ary_initialize(int argc
, VALUE
*argv
, VALUE ary
)
301 if (RARRAY_PTR(ary
) && !ARY_SHARED_P(ary
)) {
302 xfree(RARRAY(ary
)->ptr
);
304 RARRAY(ary
)->len
= 0;
305 if (rb_block_given_p()) {
306 rb_warning("given block not used");
310 rb_scan_args(argc
, argv
, "02", &size
, &val
);
311 if (argc
== 1 && !FIXNUM_P(size
)) {
312 val
= rb_check_array_type(size
);
314 rb_ary_replace(ary
, val
);
319 len
= NUM2LONG(size
);
321 rb_raise(rb_eArgError
, "negative array size");
323 if (len
> ARY_MAX_SIZE
) {
324 rb_raise(rb_eArgError
, "array size too big");
327 RESIZE_CAPA(ary
, len
);
328 if (rb_block_given_p()) {
332 rb_warn("block supersedes default value argument");
334 for (i
=0; i
<len
; i
++) {
335 rb_ary_store(ary
, i
, rb_yield(LONG2NUM(i
)));
336 RARRAY(ary
)->len
= i
+ 1;
340 memfill(RARRAY_PTR(ary
), len
, val
);
341 RARRAY(ary
)->len
= len
;
348 * Returns a new array populated with the given objects.
350 * Array.[]( 1, 'a', /^A/ )
351 * Array[ 1, 'a', /^A/ ]
356 rb_ary_s_create(int argc
, VALUE
*argv
, VALUE klass
)
358 VALUE ary
= ary_alloc(klass
);
361 rb_raise(rb_eArgError
, "negative array size");
363 RARRAY(ary
)->ptr
= ALLOC_N(VALUE
, argc
);
364 RARRAY(ary
)->aux
.capa
= argc
;
365 MEMCPY(RARRAY_PTR(ary
), argv
, VALUE
, argc
);
366 RARRAY(ary
)->len
= argc
;
372 rb_ary_store(VALUE ary
, long idx
, VALUE val
)
375 idx
+= RARRAY_LEN(ary
);
377 rb_raise(rb_eIndexError
, "index %ld out of array",
378 idx
- RARRAY_LEN(ary
));
381 else if (idx
>= ARY_MAX_SIZE
) {
382 rb_raise(rb_eIndexError
, "index %ld too big", idx
);
386 if (idx
>= ARY_CAPA(ary
)) {
387 long new_capa
= ARY_CAPA(ary
) / 2;
389 if (new_capa
< ARY_DEFAULT_SIZE
) {
390 new_capa
= ARY_DEFAULT_SIZE
;
392 if (new_capa
>= ARY_MAX_SIZE
- idx
) {
393 new_capa
= (ARY_MAX_SIZE
- idx
) / 2;
396 RESIZE_CAPA(ary
, new_capa
);
398 if (idx
> RARRAY_LEN(ary
)) {
399 rb_mem_clear(RARRAY_PTR(ary
) + RARRAY_LEN(ary
),
400 idx
-RARRAY_LEN(ary
) + 1);
403 if (idx
>= RARRAY_LEN(ary
)) {
404 RARRAY(ary
)->len
= idx
+ 1;
406 RARRAY_PTR(ary
)[idx
] = val
;
410 ary_shared_array(VALUE klass
, VALUE ary
)
412 VALUE val
= ary_alloc(klass
);
414 ary_make_shared(ary
);
415 RARRAY(val
)->ptr
= RARRAY(ary
)->ptr
;
416 RARRAY(val
)->len
= RARRAY(ary
)->len
;
417 RARRAY(val
)->aux
.shared
= RARRAY(ary
)->aux
.shared
;
418 FL_SET(val
, ELTS_SHARED
);
423 ary_shared_first(int argc
, VALUE
*argv
, VALUE ary
, int last
)
429 rb_scan_args(argc
, argv
, "1", &nv
);
431 if (n
> RARRAY_LEN(ary
)) {
435 rb_raise(rb_eArgError
, "negative array size");
438 offset
= RARRAY_LEN(ary
) - n
;
440 result
= ary_shared_array(rb_cArray
, ary
);
441 RARRAY(result
)->ptr
+= offset
;
442 RARRAY(result
)->len
= n
;
449 * array << obj -> array
451 * Append---Pushes the given object on to the end of this array. This
452 * expression returns the array itself, so several appends
453 * may be chained together.
455 * [ 1, 2 ] << "c" << "d" << [ 3, 4 ]
456 * #=> [ 1, 2, "c", "d", [ 3, 4 ] ]
461 rb_ary_push(VALUE ary
, VALUE item
)
463 rb_ary_store(ary
, RARRAY_LEN(ary
), item
);
469 * array.push(obj, ... ) -> array
471 * Append---Pushes the given object(s) on to the end of this array. This
472 * expression returns the array itself, so several appends
473 * may be chained together.
475 * a = [ "a", "b", "c" ]
476 * a.push("d", "e", "f")
477 * #=> ["a", "b", "c", "d", "e", "f"]
481 rb_ary_push_m(int argc
, VALUE
*argv
, VALUE ary
)
484 rb_ary_push(ary
, *argv
++);
490 rb_ary_pop(VALUE ary
)
493 rb_ary_modify_check(ary
);
494 if (RARRAY_LEN(ary
) == 0) return Qnil
;
495 if (!ARY_SHARED_P(ary
) &&
496 RARRAY_LEN(ary
) * 3 < ARY_CAPA(ary
) &&
497 ARY_CAPA(ary
) > ARY_DEFAULT_SIZE
)
499 RESIZE_CAPA(ary
, RARRAY_LEN(ary
) * 2);
501 n
= RARRAY_LEN(ary
)-1;
502 RARRAY(ary
)->len
= n
;
503 return RARRAY_PTR(ary
)[n
];
508 * array.pop -> obj or nil
509 * array.pop(n) -> array
511 * Removes the last element from <i>self</i> and returns it, or
512 * <code>nil</code> if the array is empty.
514 * If a number _n_ is given, returns an array of the last n elements
515 * (or less) just like <code>array.slice!(-n, n)</code> does.
517 * a = [ "a", "b", "c", "d" ]
519 * a.pop(2) #=> ["b", "c"]
524 rb_ary_pop_m(int argc
, VALUE
*argv
, VALUE ary
)
529 return rb_ary_pop(ary
);
532 rb_ary_modify_check(ary
);
533 result
= ary_shared_first(argc
, argv
, ary
, Qtrue
);
534 RARRAY(ary
)->len
-= RARRAY_LEN(result
);
539 rb_ary_shift(VALUE ary
)
543 rb_ary_modify_check(ary
);
544 if (RARRAY_LEN(ary
) == 0) return Qnil
;
545 top
= RARRAY_PTR(ary
)[0];
546 if (!ARY_SHARED_P(ary
)) {
547 if (RARRAY_LEN(ary
) < ARY_DEFAULT_SIZE
) {
548 MEMMOVE(RARRAY_PTR(ary
), RARRAY_PTR(ary
)+1, VALUE
, RARRAY_LEN(ary
)-1);
552 RARRAY_PTR(ary
)[0] = Qnil
;
553 ary_make_shared(ary
);
555 RARRAY(ary
)->ptr
++; /* shift ptr */
563 * array.shift -> obj or nil
564 * array.shift(n) -> array
566 * Returns the first element of <i>self</i> and removes it (shifting all
567 * other elements down by one). Returns <code>nil</code> if the array
570 * If a number _n_ is given, returns an array of the first n elements
571 * (or less) just like <code>array.slice!(0, n)</code> does.
573 * args = [ "-m", "-q", "filename" ]
574 * args.shift #=> "-m"
575 * args #=> ["-q", "filename"]
577 * args = [ "-m", "-q", "filename" ]
578 * args.shift(2) #=> ["-m", "-q"]
579 * args #=> ["filename"]
583 rb_ary_shift_m(int argc
, VALUE
*argv
, VALUE ary
)
589 return rb_ary_shift(ary
);
592 rb_ary_modify_check(ary
);
593 result
= ary_shared_first(argc
, argv
, ary
, Qfalse
);
594 n
= RARRAY_LEN(result
);
595 if (ARY_SHARED_P(ary
)) {
596 RARRAY(ary
)->ptr
+= n
;
597 RARRAY(ary
)->len
-= n
;
600 MEMMOVE(RARRAY_PTR(ary
), RARRAY_PTR(ary
)+n
, VALUE
, RARRAY_LEN(ary
)-n
);
601 RARRAY(ary
)->len
-= n
;
609 * array.unshift(obj, ...) -> array
611 * Prepends objects to the front of <i>array</i>.
612 * other elements up one.
614 * a = [ "b", "c", "d" ]
615 * a.unshift("a") #=> ["a", "b", "c", "d"]
616 * a.unshift(1, 2) #=> [ 1, 2, "a", "b", "c", "d"]
620 rb_ary_unshift_m(int argc
, VALUE
*argv
, VALUE ary
)
624 if (argc
== 0) return ary
;
626 if (RARRAY(ary
)->aux
.capa
<= (len
= RARRAY(ary
)->len
) + argc
) {
627 RESIZE_CAPA(ary
, len
+ argc
+ ARY_DEFAULT_SIZE
);
631 MEMMOVE(RARRAY(ary
)->ptr
+ argc
, RARRAY(ary
)->ptr
, VALUE
, len
);
632 MEMCPY(RARRAY(ary
)->ptr
, argv
, VALUE
, argc
);
633 RARRAY(ary
)->len
+= argc
;
639 rb_ary_unshift(VALUE ary
, VALUE item
)
641 return rb_ary_unshift_m(1,&item
,ary
);
644 /* faster version - use this if you don't need to treat negative offset */
646 rb_ary_elt(VALUE ary
, long offset
)
648 if (RARRAY_LEN(ary
) == 0) return Qnil
;
649 if (offset
< 0 || RARRAY_LEN(ary
) <= offset
) {
652 return RARRAY_PTR(ary
)[offset
];
656 rb_ary_entry(VALUE ary
, long offset
)
659 offset
+= RARRAY_LEN(ary
);
661 return rb_ary_elt(ary
, offset
);
665 rb_ary_subseq(VALUE ary
, long beg
, long len
)
667 VALUE klass
, ary2
, shared
;
670 if (beg
> RARRAY_LEN(ary
)) return Qnil
;
671 if (beg
< 0 || len
< 0) return Qnil
;
673 if (RARRAY_LEN(ary
) < len
|| RARRAY_LEN(ary
) < beg
+ len
) {
674 len
= RARRAY_LEN(ary
) - beg
;
676 klass
= rb_obj_class(ary
);
677 if (len
== 0) return ary_new(klass
, 0);
679 shared
= ary_make_shared(ary
);
680 ptr
= RARRAY_PTR(ary
);
681 ary2
= ary_alloc(klass
);
682 RARRAY(ary2
)->ptr
= ptr
+ beg
;
683 RARRAY(ary2
)->len
= len
;
684 RARRAY(ary2
)->aux
.shared
= shared
;
685 FL_SET(ary2
, ELTS_SHARED
);
692 * array[index] -> obj or nil
693 * array[start, length] -> an_array or nil
694 * array[range] -> an_array or nil
695 * array.slice(index) -> obj or nil
696 * array.slice(start, length) -> an_array or nil
697 * array.slice(range) -> an_array or nil
699 * Element Reference---Returns the element at _index_,
700 * or returns a subarray starting at _start_ and
701 * continuing for _length_ elements, or returns a subarray
702 * specified by _range_.
703 * Negative indices count backward from the end of the
704 * array (-1 is the last element). Returns nil if the index
705 * (or starting index) are out of range.
707 * a = [ "a", "b", "c", "d", "e" ]
708 * a[2] + a[0] + a[1] #=> "cab"
710 * a[1, 2] #=> [ "b", "c" ]
711 * a[1..3] #=> [ "b", "c", "d" ]
712 * a[4..7] #=> [ "e" ]
714 * a[-3, 3] #=> [ "c", "d", "e" ]
723 rb_ary_aref(int argc
, VALUE
*argv
, VALUE ary
)
729 beg
= NUM2LONG(argv
[0]);
730 len
= NUM2LONG(argv
[1]);
732 beg
+= RARRAY_LEN(ary
);
734 return rb_ary_subseq(ary
, beg
, len
);
737 rb_scan_args(argc
, argv
, "11", 0, 0);
740 /* special case - speeding up */
742 return rb_ary_entry(ary
, FIX2LONG(arg
));
744 /* check if idx is Range */
745 switch (rb_range_beg_len(arg
, &beg
, &len
, RARRAY_LEN(ary
), 0)) {
751 return rb_ary_subseq(ary
, beg
, len
);
753 return rb_ary_entry(ary
, NUM2LONG(arg
));
758 * array.at(index) -> obj or nil
760 * Returns the element at _index_. A
761 * negative index counts from the end of _self_. Returns +nil+
762 * if the index is out of range. See also <code>Array#[]</code>.
764 * a = [ "a", "b", "c", "d", "e" ]
770 rb_ary_at(VALUE ary
, VALUE pos
)
772 return rb_ary_entry(ary
, NUM2LONG(pos
));
777 * array.first -> obj or nil
778 * array.first(n) -> an_array
780 * Returns the first element, or the first +n+ elements, of the array.
781 * If the array is empty, the first form returns <code>nil</code>, and the
782 * second form returns an empty array.
784 * a = [ "q", "r", "s", "t" ]
786 * a.first(2) #=> ["q", "r"]
790 rb_ary_first(int argc
, VALUE
*argv
, VALUE ary
)
793 if (RARRAY_LEN(ary
) == 0) return Qnil
;
794 return RARRAY_PTR(ary
)[0];
797 return ary_shared_first(argc
, argv
, ary
, Qfalse
);
803 * array.last -> obj or nil
804 * array.last(n) -> an_array
806 * Returns the last element(s) of <i>self</i>. If the array is empty,
807 * the first form returns <code>nil</code>.
809 * a = [ "w", "x", "y", "z" ]
811 * a.last(2) #=> ["y", "z"]
815 rb_ary_last(int argc
, VALUE
*argv
, VALUE ary
)
818 if (RARRAY_LEN(ary
) == 0) return Qnil
;
819 return RARRAY_PTR(ary
)[RARRAY_LEN(ary
)-1];
822 return ary_shared_first(argc
, argv
, ary
, Qtrue
);
828 * array.fetch(index) -> obj
829 * array.fetch(index, default ) -> obj
830 * array.fetch(index) {|index| block } -> obj
832 * Tries to return the element at position <i>index</i>. If the index
833 * lies outside the array, the first form throws an
834 * <code>IndexError</code> exception, the second form returns
835 * <i>default</i>, and the third form returns the value of invoking
836 * the block, passing in the index. Negative values of <i>index</i>
837 * count from the end of the array.
839 * a = [ 11, 22, 33, 44 ]
842 * a.fetch(4, 'cat') #=> "cat"
843 * a.fetch(4) { |i| i*i } #=> 16
847 rb_ary_fetch(int argc
, VALUE
*argv
, VALUE ary
)
853 rb_scan_args(argc
, argv
, "11", &pos
, &ifnone
);
854 block_given
= rb_block_given_p();
855 if (block_given
&& argc
== 2) {
856 rb_warn("block supersedes default value argument");
861 idx
+= RARRAY_LEN(ary
);
863 if (idx
< 0 || RARRAY_LEN(ary
) <= idx
) {
864 if (block_given
) return rb_yield(pos
);
866 rb_raise(rb_eIndexError
, "index %ld out of array", idx
);
870 return RARRAY_PTR(ary
)[idx
];
875 * array.index(obj) -> int or nil
876 * array.index {|item| block} -> int or nil
878 * Returns the index of the first object in <i>self</i> such that is
879 * <code>==</code> to <i>obj</i>. If a block is given instead of an
880 * argument, returns first object for which <em>block</em> is true.
881 * Returns <code>nil</code> if no match is found.
883 * a = [ "a", "b", "c" ]
885 * a.index("z") #=> nil
886 * a.index{|x|x=="b"} #=> 1
888 * This is an alias of <code>#find_index</code>.
892 rb_ary_index(int argc
, VALUE
*argv
, VALUE ary
)
898 RETURN_ENUMERATOR(ary
, 0, 0);
899 for (i
=0; i
<RARRAY_LEN(ary
); i
++) {
900 if (RTEST(rb_yield(RARRAY_PTR(ary
)[i
]))) {
906 rb_scan_args(argc
, argv
, "01", &val
);
907 for (i
=0; i
<RARRAY_LEN(ary
); i
++) {
908 if (rb_equal(RARRAY_PTR(ary
)[i
], val
))
916 * array.rindex(obj) -> int or nil
918 * Returns the index of the last object in <i>array</i>
919 * <code>==</code> to <i>obj</i>. If a block is given instead of an
920 * argument, returns first object for which <em>block</em> is
921 * true. Returns <code>nil</code> if no match is found.
923 * a = [ "a", "b", "b", "b", "c" ]
924 * a.rindex("b") #=> 3
925 * a.rindex("z") #=> nil
926 * a.rindex{|x|x=="b"} #=> 3
930 rb_ary_rindex(int argc
, VALUE
*argv
, VALUE ary
)
933 long i
= RARRAY_LEN(ary
);
936 RETURN_ENUMERATOR(ary
, 0, 0);
938 if (RTEST(rb_yield(RARRAY_PTR(ary
)[i
])))
940 if (i
> RARRAY_LEN(ary
)) {
946 rb_scan_args(argc
, argv
, "01", &val
);
948 if (rb_equal(RARRAY_PTR(ary
)[i
], val
))
950 if (i
> RARRAY_LEN(ary
)) {
958 rb_ary_to_ary(VALUE obj
)
960 if (TYPE(obj
) == T_ARRAY
) {
963 if (rb_respond_to(obj
, rb_intern("to_ary"))) {
966 return rb_ary_new3(1, obj
);
970 rb_ary_splice(VALUE ary
, long beg
, long len
, VALUE rpl
)
974 if (len
< 0) rb_raise(rb_eIndexError
, "negative length (%ld)", len
);
976 beg
+= RARRAY_LEN(ary
);
978 beg
-= RARRAY_LEN(ary
);
979 rb_raise(rb_eIndexError
, "index %ld out of array", beg
);
982 if (RARRAY_LEN(ary
) < len
|| RARRAY_LEN(ary
) < beg
+ len
) {
983 len
= RARRAY_LEN(ary
) - beg
;
990 rpl
= rb_ary_to_ary(rpl
);
991 rlen
= RARRAY_LEN(rpl
);
994 if (beg
>= RARRAY_LEN(ary
)) {
995 if (beg
> ARY_MAX_SIZE
- rlen
) {
996 rb_raise(rb_eIndexError
, "index %ld too big", beg
);
999 if (len
>= ARY_CAPA(ary
)) {
1000 RESIZE_CAPA(ary
, len
);
1002 rb_mem_clear(RARRAY_PTR(ary
) + RARRAY_LEN(ary
), beg
- RARRAY_LEN(ary
));
1004 MEMCPY(RARRAY_PTR(ary
) + beg
, RARRAY_PTR(rpl
), VALUE
, rlen
);
1006 RARRAY(ary
)->len
= len
;
1011 if (beg
+ len
> RARRAY_LEN(ary
)) {
1012 len
= RARRAY_LEN(ary
) - beg
;
1015 alen
= RARRAY_LEN(ary
) + rlen
- len
;
1016 if (alen
>= ARY_CAPA(ary
)) {
1017 RESIZE_CAPA(ary
, alen
);
1021 MEMMOVE(RARRAY_PTR(ary
) + beg
+ rlen
, RARRAY_PTR(ary
) + beg
+ len
,
1022 VALUE
, RARRAY_LEN(ary
) - (beg
+ len
));
1023 RARRAY(ary
)->len
= alen
;
1026 MEMMOVE(RARRAY_PTR(ary
) + beg
, RARRAY_PTR(rpl
), VALUE
, rlen
);
1033 * array[index] = obj -> obj
1034 * array[start, length] = obj or an_array or nil -> obj or an_array or nil
1035 * array[range] = obj or an_array or nil -> obj or an_array or nil
1037 * Element Assignment---Sets the element at _index_,
1038 * or replaces a subarray starting at _start_ and
1039 * continuing for _length_ elements, or replaces a subarray
1040 * specified by _range_. If indices are greater than
1041 * the current capacity of the array, the array grows
1042 * automatically. A negative indices will count backward
1043 * from the end of the array. Inserts elements if _length_ is
1044 * zero. An +IndexError+ is raised if a negative index points
1045 * past the beginning of the array. See also
1046 * <code>Array#push</code>, and <code>Array#unshift</code>.
1049 * a[4] = "4"; #=> [nil, nil, nil, nil, "4"]
1050 * a[0, 3] = [ 'a', 'b', 'c' ] #=> ["a", "b", "c", nil, "4"]
1051 * a[1..2] = [ 1, 2 ] #=> ["a", 1, 2, nil, "4"]
1052 * a[0, 2] = "?" #=> ["?", 2, nil, "4"]
1053 * a[0..2] = "A" #=> ["A", "4"]
1054 * a[-1] = "Z" #=> ["A", "Z"]
1055 * a[1..-1] = nil #=> ["A", nil]
1056 * a[1..-1] = [] #=> ["A"]
1060 rb_ary_aset(int argc
, VALUE
*argv
, VALUE ary
)
1062 long offset
, beg
, len
;
1065 rb_ary_splice(ary
, NUM2LONG(argv
[0]), NUM2LONG(argv
[1]), argv
[2]);
1069 rb_raise(rb_eArgError
, "wrong number of arguments (%d for 2)", argc
);
1071 if (FIXNUM_P(argv
[0])) {
1072 offset
= FIX2LONG(argv
[0]);
1075 if (rb_range_beg_len(argv
[0], &beg
, &len
, RARRAY_LEN(ary
), 1)) {
1076 /* check if idx is Range */
1077 rb_ary_splice(ary
, beg
, len
, argv
[1]);
1081 offset
= NUM2LONG(argv
[0]);
1083 rb_ary_store(ary
, offset
, argv
[1]);
1089 * array.insert(index, obj...) -> array
1091 * Inserts the given values before the element with the given index
1092 * (which may be negative).
1095 * a.insert(2, 99) #=> ["a", "b", 99, "c", "d"]
1096 * a.insert(-2, 1, 2, 3) #=> ["a", "b", 99, "c", 1, 2, 3, "d"]
1100 rb_ary_insert(int argc
, VALUE
*argv
, VALUE ary
)
1104 if (argc
== 1) return ary
;
1106 rb_raise(rb_eArgError
, "wrong number of arguments (at least 1)");
1108 pos
= NUM2LONG(argv
[0]);
1110 pos
= RARRAY_LEN(ary
);
1115 rb_ary_splice(ary
, pos
, 0, rb_ary_new4(argc
- 1, argv
+ 1));
1121 * array.each {|item| block } -> array
1123 * Calls <i>block</i> once for each element in <i>self</i>, passing that
1124 * element as a parameter.
1126 * a = [ "a", "b", "c" ]
1127 * a.each {|x| print x, " -- " }
1135 rb_ary_each(VALUE ary
)
1139 RETURN_ENUMERATOR(ary
, 0, 0);
1140 for (i
=0; i
<RARRAY_LEN(ary
); i
++) {
1141 rb_yield(RARRAY_PTR(ary
)[i
]);
1148 * array.each_index {|index| block } -> array
1150 * Same as <code>Array#each</code>, but passes the index of the element
1151 * instead of the element itself.
1153 * a = [ "a", "b", "c" ]
1154 * a.each_index {|x| print x, " -- " }
1162 rb_ary_each_index(VALUE ary
)
1165 RETURN_ENUMERATOR(ary
, 0, 0);
1167 for (i
=0; i
<RARRAY_LEN(ary
); i
++) {
1168 rb_yield(LONG2NUM(i
));
1175 * array.reverse_each {|item| block }
1177 * Same as <code>Array#each</code>, but traverses <i>self</i> in reverse
1180 * a = [ "a", "b", "c" ]
1181 * a.reverse_each {|x| print x, " " }
1189 rb_ary_reverse_each(VALUE ary
)
1193 RETURN_ENUMERATOR(ary
, 0, 0);
1194 len
= RARRAY_LEN(ary
);
1196 rb_yield(RARRAY_PTR(ary
)[len
]);
1197 if (RARRAY_LEN(ary
) < len
) {
1198 len
= RARRAY_LEN(ary
);
1206 * array.length -> int
1208 * Returns the number of elements in <i>self</i>. May be zero.
1210 * [ 1, 2, 3, 4, 5 ].length #=> 5
1214 rb_ary_length(VALUE ary
)
1216 long len
= RARRAY_LEN(ary
);
1217 return LONG2NUM(len
);
1222 * array.empty? -> true or false
1224 * Returns <code>true</code> if <i>self</i> array contains no elements.
1226 * [].empty? #=> true
1230 rb_ary_empty_p(VALUE ary
)
1232 if (RARRAY_LEN(ary
) == 0)
1238 rb_ary_dup(VALUE ary
)
1240 VALUE dup
= rb_ary_new2(RARRAY_LEN(ary
));
1243 MEMCPY(RARRAY_PTR(dup
), RARRAY_PTR(ary
), VALUE
, RARRAY_LEN(ary
));
1244 RARRAY(dup
)->len
= RARRAY_LEN(ary
);
1249 extern VALUE rb_output_fs
;
1252 recursive_join(VALUE ary
, VALUE argp
, int recur
)
1254 VALUE
*arg
= (VALUE
*)argp
;
1256 return rb_usascii_str_new2("[...]");
1258 return rb_ary_join(arg
[0], arg
[1]);
1262 rb_ary_join(VALUE ary
, VALUE sep
)
1266 int untrust
= Qfalse
;
1269 if (RARRAY_LEN(ary
) == 0) return rb_str_new(0, 0);
1270 if (OBJ_TAINTED(ary
) || OBJ_TAINTED(sep
)) taint
= Qtrue
;
1271 if (OBJ_UNTRUSTED(ary
) || OBJ_UNTRUSTED(sep
)) untrust
= Qtrue
;
1273 for (i
=0; i
<RARRAY_LEN(ary
); i
++) {
1274 tmp
= rb_check_string_type(RARRAY_PTR(ary
)[i
]);
1275 len
+= NIL_P(tmp
) ? 10 : RSTRING_LEN(tmp
);
1279 len
+= RSTRING_LEN(sep
) * (RARRAY_LEN(ary
) - 1);
1281 result
= rb_str_buf_new(len
);
1282 for (i
=0; i
<RARRAY_LEN(ary
); i
++) {
1283 tmp
= RARRAY_PTR(ary
)[i
];
1284 switch (TYPE(tmp
)) {
1293 tmp
= rb_exec_recursive(recursive_join
, ary
, (VALUE
)args
);
1297 tmp
= rb_obj_as_string(tmp
);
1299 if (i
> 0 && !NIL_P(sep
))
1300 rb_str_buf_append(result
, sep
);
1301 rb_str_buf_append(result
, tmp
);
1302 if (OBJ_TAINTED(tmp
)) taint
= Qtrue
;
1303 if (OBJ_UNTRUSTED(tmp
)) untrust
= Qtrue
;
1306 if (taint
) OBJ_TAINT(result
);
1307 if (untrust
) OBJ_UNTRUST(result
);
1313 * array.join(sep=$,) -> str
1315 * Returns a string created by converting each element of the array to
1316 * a string, separated by <i>sep</i>.
1318 * [ "a", "b", "c" ].join #=> "abc"
1319 * [ "a", "b", "c" ].join("-") #=> "a-b-c"
1323 rb_ary_join_m(int argc
, VALUE
*argv
, VALUE ary
)
1327 rb_scan_args(argc
, argv
, "01", &sep
);
1328 if (NIL_P(sep
)) sep
= rb_output_fs
;
1330 return rb_ary_join(ary
, sep
);
1334 inspect_ary(VALUE ary
, VALUE dummy
, int recur
)
1336 int tainted
= OBJ_TAINTED(ary
);
1337 int untrust
= OBJ_UNTRUSTED(ary
);
1341 if (recur
) return rb_tainted_str_new2("[...]");
1342 str
= rb_str_buf_new2("[");
1343 for (i
=0; i
<RARRAY_LEN(ary
); i
++) {
1344 s
= rb_inspect(RARRAY_PTR(ary
)[i
]);
1345 if (OBJ_TAINTED(s
)) tainted
= Qtrue
;
1346 if (OBJ_UNTRUSTED(s
)) untrust
= Qtrue
;
1347 if (i
> 0) rb_str_buf_cat2(str
, ", ");
1348 rb_str_buf_append(str
, s
);
1350 rb_str_buf_cat2(str
, "]");
1351 if (tainted
) OBJ_TAINT(str
);
1352 if (untrust
) OBJ_UNTRUST(str
);
1358 * array.to_s -> string
1359 * array.inspect -> string
1361 * Create a printable version of <i>array</i>.
1365 rb_ary_inspect(VALUE ary
)
1367 if (RARRAY_LEN(ary
) == 0) return rb_usascii_str_new2("[]");
1368 return rb_exec_recursive(inspect_ary
, ary
, 0);
1372 rb_ary_to_s(VALUE ary
)
1374 return rb_ary_inspect(ary
);
1379 * array.to_a -> array
1381 * Returns _self_. If called on a subclass of Array, converts
1382 * the receiver to an Array object.
1386 rb_ary_to_a(VALUE ary
)
1388 if (rb_obj_class(ary
) != rb_cArray
) {
1389 VALUE dup
= rb_ary_new2(RARRAY_LEN(ary
));
1390 rb_ary_replace(dup
, ary
);
1398 * array.to_ary -> array
1404 rb_ary_to_ary_m(VALUE ary
)
1410 rb_ary_reverse(VALUE ary
)
1416 if (RARRAY_LEN(ary
) > 1) {
1417 p1
= RARRAY_PTR(ary
);
1418 p2
= p1
+ RARRAY_LEN(ary
) - 1; /* points last item */
1431 * array.reverse! -> array
1433 * Reverses _self_ in place.
1435 * a = [ "a", "b", "c" ]
1436 * a.reverse! #=> ["c", "b", "a"]
1437 * a #=> ["c", "b", "a"]
1441 rb_ary_reverse_bang(VALUE ary
)
1443 return rb_ary_reverse(ary
);
1448 * array.reverse -> an_array
1450 * Returns a new array containing <i>self</i>'s elements in reverse order.
1452 * [ "a", "b", "c" ].reverse #=> ["c", "b", "a"]
1453 * [ 1 ].reverse #=> [1]
1457 rb_ary_reverse_m(VALUE ary
)
1459 return rb_ary_reverse(rb_ary_dup(ary
));
1462 struct ary_sort_data
{
1471 sort_optimizable_count
1474 #define STRING_P(s) (TYPE(s) == T_STRING && CLASS_OF(s) == rb_cString)
1476 #define SORT_OPTIMIZABLE_BIT(type) (1U << TOKEN_PASTE(sort_opt_,type))
1477 #define SORT_OPTIMIZABLE(data, type) \
1478 ((data->opt_inited & SORT_OPTIMIZABLE_BIT(type)) ? \
1479 (data->opt_methods & SORT_OPTIMIZABLE_BIT(type)) : \
1480 ((data->opt_inited |= SORT_OPTIMIZABLE_BIT(type)), \
1481 rb_method_basic_definition_p(TOKEN_PASTE(rb_c,type), id_cmp) && \
1482 (data->opt_methods |= SORT_OPTIMIZABLE_BIT(type))))
1485 sort_reentered(VALUE ary
)
1487 if (RBASIC(ary
)->klass
) {
1488 rb_raise(rb_eRuntimeError
, "sort reentered");
1494 sort_1(const void *ap
, const void *bp
, void *dummy
)
1496 struct ary_sort_data
*data
= dummy
;
1497 VALUE retval
= sort_reentered(data
->ary
);
1498 VALUE a
= *(const VALUE
*)ap
, b
= *(const VALUE
*)bp
;
1501 retval
= rb_yield_values(2, a
, b
);
1502 n
= rb_cmpint(retval
, a
, b
);
1503 sort_reentered(data
->ary
);
1508 sort_2(const void *ap
, const void *bp
, void *dummy
)
1510 struct ary_sort_data
*data
= dummy
;
1511 VALUE retval
= sort_reentered(data
->ary
);
1512 VALUE a
= *(const VALUE
*)ap
, b
= *(const VALUE
*)bp
;
1515 if (FIXNUM_P(a
) && FIXNUM_P(b
) && SORT_OPTIMIZABLE(data
, Fixnum
)) {
1516 if ((long)a
> (long)b
) return 1;
1517 if ((long)a
< (long)b
) return -1;
1520 if (STRING_P(a
) && STRING_P(b
) && SORT_OPTIMIZABLE(data
, String
)) {
1521 return rb_str_cmp(a
, b
);
1524 retval
= rb_funcall(a
, id_cmp
, 1, b
);
1525 n
= rb_cmpint(retval
, a
, b
);
1526 sort_reentered(data
->ary
);
1533 * array.sort! -> array
1534 * array.sort! {| a,b | block } -> array
1536 * Sorts _self_. Comparisons for
1537 * the sort will be done using the <code><=></code> operator or using
1538 * an optional code block. The block implements a comparison between
1539 * <i>a</i> and <i>b</i>, returning -1, 0, or +1. See also
1540 * <code>Enumerable#sort_by</code>.
1542 * a = [ "d", "a", "e", "c", "b" ]
1543 * a.sort #=> ["a", "b", "c", "d", "e"]
1544 * a.sort {|x,y| y <=> x } #=> ["e", "d", "c", "b", "a"]
1548 rb_ary_sort_bang(VALUE ary
)
1551 if (RARRAY_LEN(ary
) > 1) {
1552 VALUE tmp
= ary_make_shared(ary
);
1553 struct ary_sort_data data
;
1555 RBASIC(tmp
)->klass
= 0;
1557 data
.opt_methods
= 0;
1558 data
.opt_inited
= 0;
1559 ruby_qsort(RARRAY_PTR(tmp
), RARRAY_LEN(tmp
), sizeof(VALUE
),
1560 rb_block_given_p()?sort_1
:sort_2
, &data
);
1561 if (RARRAY(ary
)->ptr
!= RARRAY(tmp
)->ptr
) {
1562 if (!ARY_SHARED_P(ary
)) xfree(RARRAY(ary
)->ptr
);
1563 RARRAY(ary
)->ptr
= RARRAY(tmp
)->ptr
;
1564 RARRAY(ary
)->len
= RARRAY(tmp
)->len
;
1565 RARRAY(ary
)->aux
.capa
= RARRAY(tmp
)->aux
.capa
;
1566 FL_SET(ary
, ELTS_SHARED
);
1568 FL_UNSET(ary
, ELTS_SHARED
);
1569 RARRAY(tmp
)->ptr
= 0;
1570 RARRAY(tmp
)->len
= 0;
1571 RARRAY(tmp
)->aux
.capa
= 0;
1572 RBASIC(tmp
)->klass
= rb_cArray
;
1579 * array.sort -> an_array
1580 * array.sort {| a,b | block } -> an_array
1582 * Returns a new array created by sorting <i>self</i>. Comparisons for
1583 * the sort will be done using the <code><=></code> operator or using
1584 * an optional code block. The block implements a comparison between
1585 * <i>a</i> and <i>b</i>, returning -1, 0, or +1. See also
1586 * <code>Enumerable#sort_by</code>.
1588 * a = [ "d", "a", "e", "c", "b" ]
1589 * a.sort #=> ["a", "b", "c", "d", "e"]
1590 * a.sort {|x,y| y <=> x } #=> ["e", "d", "c", "b", "a"]
1594 rb_ary_sort(VALUE ary
)
1596 ary
= rb_ary_dup(ary
);
1597 rb_ary_sort_bang(ary
);
1604 * array.collect {|item| block } -> an_array
1605 * array.map {|item| block } -> an_array
1607 * Invokes <i>block</i> once for each element of <i>self</i>. Creates a
1608 * new array containing the values returned by the block.
1609 * See also <code>Enumerable#collect</code>.
1611 * a = [ "a", "b", "c", "d" ]
1612 * a.collect {|x| x + "!" } #=> ["a!", "b!", "c!", "d!"]
1613 * a #=> ["a", "b", "c", "d"]
1617 rb_ary_collect(VALUE ary
)
1622 RETURN_ENUMERATOR(ary
, 0, 0);
1623 collect
= rb_ary_new2(RARRAY_LEN(ary
));
1624 for (i
= 0; i
< RARRAY_LEN(ary
); i
++) {
1625 rb_ary_push(collect
, rb_yield(RARRAY_PTR(ary
)[i
]));
1633 * array.collect! {|item| block } -> array
1634 * array.map! {|item| block } -> array
1636 * Invokes the block once for each element of _self_, replacing the
1637 * element with the value returned by _block_.
1638 * See also <code>Enumerable#collect</code>.
1640 * a = [ "a", "b", "c", "d" ]
1641 * a.collect! {|x| x + "!" }
1642 * a #=> [ "a!", "b!", "c!", "d!" ]
1646 rb_ary_collect_bang(VALUE ary
)
1650 RETURN_ENUMERATOR(ary
, 0, 0);
1652 for (i
= 0; i
< RARRAY_LEN(ary
); i
++) {
1653 rb_ary_store(ary
, i
, rb_yield(RARRAY_PTR(ary
)[i
]));
1659 rb_get_values_at(VALUE obj
, long olen
, int argc
, VALUE
*argv
, VALUE (*func
) (VALUE
, long))
1661 VALUE result
= rb_ary_new2(argc
);
1662 long beg
, len
, i
, j
;
1664 for (i
=0; i
<argc
; i
++) {
1665 if (FIXNUM_P(argv
[i
])) {
1666 rb_ary_push(result
, (*func
)(obj
, FIX2LONG(argv
[i
])));
1669 /* check if idx is Range */
1670 switch (rb_range_beg_len(argv
[i
], &beg
, &len
, olen
, 0)) {
1676 for (j
=0; j
<len
; j
++) {
1677 rb_ary_push(result
, (*func
)(obj
, j
+beg
));
1681 rb_ary_push(result
, (*func
)(obj
, NUM2LONG(argv
[i
])));
1688 * array.values_at(selector,... ) -> an_array
1690 * Returns an array containing the elements in
1691 * _self_ corresponding to the given selector(s). The selectors
1692 * may be either integer indices or ranges.
1693 * See also <code>Array#select</code>.
1695 * a = %w{ a b c d e f }
1696 * a.values_at(1, 3, 5)
1697 * a.values_at(1, 3, 5, 7)
1698 * a.values_at(-1, -3, -5, -7)
1699 * a.values_at(1..3, 2...5)
1703 rb_ary_values_at(int argc
, VALUE
*argv
, VALUE ary
)
1705 return rb_get_values_at(ary
, RARRAY_LEN(ary
), argc
, argv
, rb_ary_entry
);
1711 * array.select {|item| block } -> an_array
1713 * Invokes the block passing in successive elements from <i>array</i>,
1714 * returning an array containing those elements for which the block
1715 * returns a true value (equivalent to <code>Enumerable#select</code>).
1717 * a = %w{ a b c d e f }
1718 * a.select {|v| v =~ /[aeiou]/} #=> ["a", "e"]
1722 rb_ary_select(VALUE ary
)
1727 RETURN_ENUMERATOR(ary
, 0, 0);
1728 result
= rb_ary_new2(RARRAY_LEN(ary
));
1729 for (i
= 0; i
< RARRAY_LEN(ary
); i
++) {
1730 if (RTEST(rb_yield(RARRAY_PTR(ary
)[i
]))) {
1731 rb_ary_push(result
, rb_ary_elt(ary
, i
));
1739 * array.delete(obj) -> obj or nil
1740 * array.delete(obj) { block } -> obj or nil
1742 * Deletes items from <i>self</i> that are equal to <i>obj</i>. If
1743 * the item is not found, returns <code>nil</code>. If the optional
1744 * code block is given, returns the result of <i>block</i> if the item
1747 * a = [ "a", "b", "b", "b", "c" ]
1748 * a.delete("b") #=> "b"
1750 * a.delete("z") #=> nil
1751 * a.delete("z") { "not found" } #=> "not found"
1755 rb_ary_delete(VALUE ary
, VALUE item
)
1760 for (i1
= i2
= 0; i1
< RARRAY_LEN(ary
); i1
++) {
1761 VALUE e
= RARRAY_PTR(ary
)[i1
];
1763 if (rb_equal(e
, item
)) {
1768 rb_ary_store(ary
, i2
, e
);
1772 if (RARRAY_LEN(ary
) == i2
) {
1773 if (rb_block_given_p()) {
1774 return rb_yield(item
);
1780 if (RARRAY_LEN(ary
) > i2
) {
1781 RARRAY(ary
)->len
= i2
;
1782 if (i2
* 2 < ARY_CAPA(ary
) &&
1783 ARY_CAPA(ary
) > ARY_DEFAULT_SIZE
) {
1784 RESIZE_CAPA(ary
, i2
*2);
1792 rb_ary_delete_at(VALUE ary
, long pos
)
1794 long len
= RARRAY_LEN(ary
);
1797 if (pos
>= len
) return Qnil
;
1800 if (pos
< 0) return Qnil
;
1804 del
= RARRAY_PTR(ary
)[pos
];
1805 MEMMOVE(RARRAY_PTR(ary
)+pos
, RARRAY_PTR(ary
)+pos
+1, VALUE
,
1806 RARRAY_LEN(ary
)-pos
-1);
1814 * array.delete_at(index) -> obj or nil
1816 * Deletes the element at the specified index, returning that element,
1817 * or <code>nil</code> if the index is out of range. See also
1818 * <code>Array#slice!</code>.
1820 * a = %w( ant bat cat dog )
1821 * a.delete_at(2) #=> "cat"
1822 * a #=> ["ant", "bat", "dog"]
1823 * a.delete_at(99) #=> nil
1827 rb_ary_delete_at_m(VALUE ary
, VALUE pos
)
1829 return rb_ary_delete_at(ary
, NUM2LONG(pos
));
1834 * array.slice!(index) -> obj or nil
1835 * array.slice!(start, length) -> sub_array or nil
1836 * array.slice!(range) -> sub_array or nil
1838 * Deletes the element(s) given by an index (optionally with a length)
1839 * or by a range. Returns the deleted object, subarray, or
1840 * <code>nil</code> if the index is out of range.
1842 * a = [ "a", "b", "c" ]
1843 * a.slice!(1) #=> "b"
1845 * a.slice!(-1) #=> "c"
1847 * a.slice!(100) #=> nil
1852 rb_ary_slice_bang(int argc
, VALUE
*argv
, VALUE ary
)
1855 long pos
, len
, orig_len
;
1857 rb_ary_modify_check(ary
);
1858 if (rb_scan_args(argc
, argv
, "11", &arg1
, &arg2
) == 2) {
1859 pos
= NUM2LONG(arg1
);
1860 len
= NUM2LONG(arg2
);
1862 if (len
< 0) return Qnil
;
1863 orig_len
= RARRAY_LEN(ary
);
1866 if (pos
< 0) return Qnil
;
1868 else if (orig_len
< pos
) return Qnil
;
1869 if (orig_len
< pos
+ len
) {
1870 len
= orig_len
- pos
;
1872 if (len
== 0) return rb_ary_new2(0);
1873 arg2
= rb_ary_new4(len
, RARRAY_PTR(ary
)+pos
);
1874 RBASIC(arg2
)->klass
= rb_obj_class(ary
);
1875 rb_ary_splice(ary
, pos
, len
, Qundef
);
1879 if (!FIXNUM_P(arg1
)) {
1880 switch (rb_range_beg_len(arg1
, &pos
, &len
, RARRAY_LEN(ary
), 0)) {
1883 goto delete_pos_len
;
1893 return rb_ary_delete_at(ary
, NUM2LONG(arg1
));
1898 * array.reject! {|item| block } -> array or nil
1900 * Equivalent to <code>Array#delete_if</code>, deleting elements from
1901 * _self_ for which the block evaluates to true, but returns
1902 * <code>nil</code> if no changes were made. Also see
1903 * <code>Enumerable#reject</code>.
1907 rb_ary_reject_bang(VALUE ary
)
1911 RETURN_ENUMERATOR(ary
, 0, 0);
1913 for (i1
= i2
= 0; i1
< RARRAY_LEN(ary
); i1
++) {
1914 VALUE v
= RARRAY_PTR(ary
)[i1
];
1915 if (RTEST(rb_yield(v
))) continue;
1917 rb_ary_store(ary
, i2
, v
);
1922 if (RARRAY_LEN(ary
) == i2
) return Qnil
;
1923 if (i2
< RARRAY_LEN(ary
))
1924 RARRAY(ary
)->len
= i2
;
1930 * array.reject {|item| block } -> an_array
1932 * Returns a new array containing the items in _self_
1933 * for which the block is not true.
1937 rb_ary_reject(VALUE ary
)
1939 RETURN_ENUMERATOR(ary
, 0, 0);
1940 ary
= rb_ary_dup(ary
);
1941 rb_ary_reject_bang(ary
);
1947 * array.delete_if {|item| block } -> array
1949 * Deletes every element of <i>self</i> for which <i>block</i> evaluates
1950 * to <code>true</code>.
1952 * a = [ "a", "b", "c" ]
1953 * a.delete_if {|x| x >= "b" } #=> ["a"]
1957 rb_ary_delete_if(VALUE ary
)
1959 RETURN_ENUMERATOR(ary
, 0, 0);
1960 rb_ary_reject_bang(ary
);
1965 take_i(VALUE val
, VALUE
*args
, int argc
, VALUE
*argv
)
1967 if (args
[1]-- == 0) rb_iter_break();
1968 if (argc
> 1) val
= rb_ary_new4(argc
, argv
);
1969 rb_ary_push(args
[0], val
);
1974 take_items(VALUE obj
, long n
)
1976 VALUE result
= rb_ary_new2(n
);
1979 args
[0] = result
; args
[1] = (VALUE
)n
;
1980 rb_block_call(obj
, rb_intern("each"), 0, 0, take_i
, (VALUE
)args
);
1987 * array.zip(arg, ...) -> an_array
1988 * array.zip(arg, ...) {| arr | block } -> nil
1990 * Converts any arguments to arrays, then merges elements of
1991 * <i>self</i> with corresponding elements from each argument. This
1992 * generates a sequence of <code>self.size</code> <em>n</em>-element
1993 * arrays, where <em>n</em> is one more that the count of arguments. If
1994 * the size of any argument is less than <code>enumObj.size</code>,
1995 * <code>nil</code> values are supplied. If a block given, it is
1996 * invoked for each output array, otherwise an array of arrays is
2001 * [1,2,3].zip(a, b) #=> [[1, 4, 7], [2, 5, 8], [3, 6, 9]]
2002 * [1,2].zip(a,b) #=> [[1, 4, 7], [2, 5, 8]]
2003 * a.zip([1,2],[8]) #=> [[4,1,8], [5,2,nil], [6,nil,nil]]
2007 rb_ary_zip(int argc
, VALUE
*argv
, VALUE ary
)
2011 VALUE result
= Qnil
;
2013 len
= RARRAY_LEN(ary
);
2014 for (i
=0; i
<argc
; i
++) {
2015 argv
[i
] = take_items(argv
[i
], len
);
2017 if (!rb_block_given_p()) {
2018 result
= rb_ary_new2(len
);
2021 for (i
=0; i
<RARRAY_LEN(ary
); i
++) {
2022 VALUE tmp
= rb_ary_new2(argc
+1);
2024 rb_ary_push(tmp
, rb_ary_elt(ary
, i
));
2025 for (j
=0; j
<argc
; j
++) {
2026 rb_ary_push(tmp
, rb_ary_elt(argv
[j
], i
));
2028 if (NIL_P(result
)) {
2032 rb_ary_push(result
, tmp
);
2040 * array.transpose -> an_array
2042 * Assumes that <i>self</i> is an array of arrays and transposes the
2045 * a = [[1,2], [3,4], [5,6]]
2046 * a.transpose #=> [[1, 3, 5], [2, 4, 6]]
2050 rb_ary_transpose(VALUE ary
)
2052 long elen
= -1, alen
, i
, j
;
2053 VALUE tmp
, result
= 0;
2055 alen
= RARRAY_LEN(ary
);
2056 if (alen
== 0) return rb_ary_dup(ary
);
2057 for (i
=0; i
<alen
; i
++) {
2058 tmp
= to_ary(rb_ary_elt(ary
, i
));
2059 if (elen
< 0) { /* first element */
2060 elen
= RARRAY_LEN(tmp
);
2061 result
= rb_ary_new2(elen
);
2062 for (j
=0; j
<elen
; j
++) {
2063 rb_ary_store(result
, j
, rb_ary_new2(alen
));
2066 else if (elen
!= RARRAY_LEN(tmp
)) {
2067 rb_raise(rb_eIndexError
, "element size differs (%ld should be %ld)",
2068 RARRAY_LEN(tmp
), elen
);
2070 for (j
=0; j
<elen
; j
++) {
2071 rb_ary_store(rb_ary_elt(result
, j
), i
, rb_ary_elt(tmp
, j
));
2079 * array.replace(other_array) -> array
2081 * Replaces the contents of <i>self</i> with the contents of
2082 * <i>other_array</i>, truncating or expanding if necessary.
2084 * a = [ "a", "b", "c", "d", "e" ]
2085 * a.replace([ "x", "y", "z" ]) #=> ["x", "y", "z"]
2086 * a #=> ["x", "y", "z"]
2090 rb_ary_replace(VALUE copy
, VALUE orig
)
2095 orig
= to_ary(orig
);
2096 rb_ary_modify_check(copy
);
2097 if (copy
== orig
) return copy
;
2098 shared
= ary_make_shared(orig
);
2099 if (!ARY_SHARED_P(copy
)) {
2100 ptr
= RARRAY(copy
)->ptr
;
2103 RARRAY(copy
)->ptr
= RARRAY(orig
)->ptr
;
2104 RARRAY(copy
)->len
= RARRAY(orig
)->len
;
2105 RARRAY(copy
)->aux
.shared
= shared
;
2106 FL_SET(copy
, ELTS_SHARED
);
2113 * array.clear -> array
2115 * Removes all elements from _self_.
2117 * a = [ "a", "b", "c", "d", "e" ]
2122 rb_ary_clear(VALUE ary
)
2125 RARRAY(ary
)->len
= 0;
2126 if (ARY_DEFAULT_SIZE
* 2 < ARY_CAPA(ary
)) {
2127 RESIZE_CAPA(ary
, ARY_DEFAULT_SIZE
* 2);
2134 * array.fill(obj) -> array
2135 * array.fill(obj, start [, length]) -> array
2136 * array.fill(obj, range ) -> array
2137 * array.fill {|index| block } -> array
2138 * array.fill(start [, length] ) {|index| block } -> array
2139 * array.fill(range) {|index| block } -> array
2141 * The first three forms set the selected elements of <i>self</i> (which
2142 * may be the entire array) to <i>obj</i>. A <i>start</i> of
2143 * <code>nil</code> is equivalent to zero. A <i>length</i> of
2144 * <code>nil</code> is equivalent to <i>self.length</i>. The last three
2145 * forms fill the array with the value of the block. The block is
2146 * passed the absolute index of each element to be filled.
2148 * a = [ "a", "b", "c", "d" ]
2149 * a.fill("x") #=> ["x", "x", "x", "x"]
2150 * a.fill("z", 2, 2) #=> ["x", "x", "z", "z"]
2151 * a.fill("y", 0..1) #=> ["y", "y", "z", "z"]
2152 * a.fill {|i| i*i} #=> [0, 1, 4, 9]
2153 * a.fill(-2) {|i| i*i*i} #=> [0, 1, 8, 27]
2157 rb_ary_fill(int argc
, VALUE
*argv
, VALUE ary
)
2159 VALUE item
, arg1
, arg2
;
2160 long beg
= 0, end
= 0, len
= 0;
2162 int block_p
= Qfalse
;
2164 if (rb_block_given_p()) {
2166 rb_scan_args(argc
, argv
, "02", &arg1
, &arg2
);
2167 argc
+= 1; /* hackish */
2170 rb_scan_args(argc
, argv
, "12", &item
, &arg1
, &arg2
);
2175 len
= RARRAY_LEN(ary
);
2178 if (rb_range_beg_len(arg1
, &beg
, &len
, RARRAY_LEN(ary
), 1)) {
2183 beg
= NIL_P(arg1
) ? 0 : NUM2LONG(arg1
);
2185 beg
= RARRAY_LEN(ary
) + beg
;
2186 if (beg
< 0) beg
= 0;
2188 len
= NIL_P(arg2
) ? RARRAY_LEN(ary
) - beg
: NUM2LONG(arg2
);
2195 if (beg
>= ARY_MAX_SIZE
|| len
> ARY_MAX_SIZE
- beg
) {
2196 rb_raise(rb_eArgError
, "argument too big");
2199 if (RARRAY_LEN(ary
) < end
) {
2200 if (end
>= ARY_CAPA(ary
)) {
2201 RESIZE_CAPA(ary
, end
);
2203 rb_mem_clear(RARRAY_PTR(ary
) + RARRAY_LEN(ary
), end
- RARRAY_LEN(ary
));
2204 RARRAY(ary
)->len
= end
;
2211 for (i
=beg
; i
<end
; i
++) {
2212 v
= rb_yield(LONG2NUM(i
));
2213 if (i
>=RARRAY_LEN(ary
)) break;
2214 RARRAY_PTR(ary
)[i
] = v
;
2218 p
= RARRAY_PTR(ary
) + beg
;
2229 * array + other_array -> an_array
2231 * Concatenation---Returns a new array built by concatenating the
2232 * two arrays together to produce a third array.
2234 * [ 1, 2, 3 ] + [ 4, 5 ] #=> [ 1, 2, 3, 4, 5 ]
2238 rb_ary_plus(VALUE x
, VALUE y
)
2244 len
= RARRAY_LEN(x
) + RARRAY_LEN(y
);
2245 z
= rb_ary_new2(len
);
2246 MEMCPY(RARRAY_PTR(z
), RARRAY_PTR(x
), VALUE
, RARRAY_LEN(x
));
2247 MEMCPY(RARRAY_PTR(z
) + RARRAY_LEN(x
), RARRAY_PTR(y
), VALUE
, RARRAY_LEN(y
));
2248 RARRAY(z
)->len
= len
;
2254 * array.concat(other_array) -> array
2256 * Appends the elements in other_array to _self_.
2258 * [ "a", "b" ].concat( ["c", "d"] ) #=> [ "a", "b", "c", "d" ]
2263 rb_ary_concat(VALUE x
, VALUE y
)
2266 if (RARRAY_LEN(y
) > 0) {
2267 rb_ary_splice(x
, RARRAY_LEN(x
), 0, y
);
2275 * array * int -> an_array
2276 * array * str -> a_string
2278 * Repetition---With a String argument, equivalent to
2279 * self.join(str). Otherwise, returns a new array
2280 * built by concatenating the _int_ copies of _self_.
2283 * [ 1, 2, 3 ] * 3 #=> [ 1, 2, 3, 1, 2, 3, 1, 2, 3 ]
2284 * [ 1, 2, 3 ] * "," #=> "1,2,3"
2289 rb_ary_times(VALUE ary
, VALUE times
)
2294 tmp
= rb_check_string_type(times
);
2296 return rb_ary_join(ary
, tmp
);
2299 len
= NUM2LONG(times
);
2300 if (len
== 0) return ary_new(rb_obj_class(ary
), 0);
2302 rb_raise(rb_eArgError
, "negative argument");
2304 if (ARY_MAX_SIZE
/len
< RARRAY_LEN(ary
)) {
2305 rb_raise(rb_eArgError
, "argument too big");
2307 len
*= RARRAY_LEN(ary
);
2309 ary2
= ary_new(rb_obj_class(ary
), len
);
2310 RARRAY(ary2
)->len
= len
;
2312 for (i
=0; i
<len
; i
+=RARRAY_LEN(ary
)) {
2313 MEMCPY(RARRAY_PTR(ary2
)+i
, RARRAY_PTR(ary
), VALUE
, RARRAY_LEN(ary
));
2315 OBJ_INFECT(ary2
, ary
);
2322 * array.assoc(obj) -> an_array or nil
2324 * Searches through an array whose elements are also arrays
2325 * comparing _obj_ with the first element of each contained array
2327 * Returns the first contained array that matches (that
2328 * is, the first associated array),
2329 * or +nil+ if no match is found.
2330 * See also <code>Array#rassoc</code>.
2332 * s1 = [ "colors", "red", "blue", "green" ]
2333 * s2 = [ "letters", "a", "b", "c" ]
2335 * a = [ s1, s2, s3 ]
2336 * a.assoc("letters") #=> [ "letters", "a", "b", "c" ]
2337 * a.assoc("foo") #=> nil
2341 rb_ary_assoc(VALUE ary
, VALUE key
)
2346 for (i
= 0; i
< RARRAY_LEN(ary
); ++i
) {
2347 v
= rb_check_array_type(RARRAY_PTR(ary
)[i
]);
2348 if (!NIL_P(v
) && RARRAY_LEN(v
) > 0 &&
2349 rb_equal(RARRAY_PTR(v
)[0], key
))
2357 * array.rassoc(obj) -> an_array or nil
2359 * Searches through the array whose elements are also arrays. Compares
2360 * _obj_ with the second element of each contained array using
2361 * <code>==</code>. Returns the first contained array that matches. See
2362 * also <code>Array#assoc</code>.
2364 * a = [ [ 1, "one"], [2, "two"], [3, "three"], ["ii", "two"] ]
2365 * a.rassoc("two") #=> [2, "two"]
2366 * a.rassoc("four") #=> nil
2370 rb_ary_rassoc(VALUE ary
, VALUE value
)
2375 for (i
= 0; i
< RARRAY_LEN(ary
); ++i
) {
2376 v
= RARRAY_PTR(ary
)[i
];
2377 if (TYPE(v
) == T_ARRAY
&&
2378 RARRAY_LEN(v
) > 1 &&
2379 rb_equal(RARRAY_PTR(v
)[1], value
))
2386 recursive_equal(VALUE ary1
, VALUE ary2
, int recur
)
2390 if (recur
) return Qfalse
;
2391 for (i
=0; i
<RARRAY_LEN(ary1
); i
++) {
2392 if (!rb_equal(rb_ary_elt(ary1
, i
), rb_ary_elt(ary2
, i
)))
2400 * array == other_array -> bool
2402 * Equality---Two arrays are equal if they contain the same number
2403 * of elements and if each element is equal to (according to
2404 * Object.==) the corresponding element in the other array.
2406 * [ "a", "c" ] == [ "a", "c", 7 ] #=> false
2407 * [ "a", "c", 7 ] == [ "a", "c", 7 ] #=> true
2408 * [ "a", "c", 7 ] == [ "a", "d", "f" ] #=> false
2413 rb_ary_equal(VALUE ary1
, VALUE ary2
)
2415 if (ary1
== ary2
) return Qtrue
;
2416 if (TYPE(ary2
) != T_ARRAY
) {
2417 if (!rb_respond_to(ary2
, rb_intern("to_ary"))) {
2420 return rb_equal(ary2
, ary1
);
2422 if (RARRAY_LEN(ary1
) != RARRAY_LEN(ary2
)) return Qfalse
;
2423 return rb_exec_recursive(recursive_equal
, ary1
, ary2
);
2427 recursive_eql(VALUE ary1
, VALUE ary2
, int recur
)
2431 if (recur
) return Qfalse
;
2432 for (i
=0; i
<RARRAY_LEN(ary1
); i
++) {
2433 if (!rb_eql(rb_ary_elt(ary1
, i
), rb_ary_elt(ary2
, i
)))
2441 * array.eql?(other) -> true or false
2443 * Returns <code>true</code> if _array_ and _other_ are the same object,
2444 * or are both arrays with the same content.
2448 rb_ary_eql(VALUE ary1
, VALUE ary2
)
2450 if (ary1
== ary2
) return Qtrue
;
2451 if (TYPE(ary2
) != T_ARRAY
) return Qfalse
;
2452 if (RARRAY_LEN(ary1
) != RARRAY_LEN(ary2
)) return Qfalse
;
2453 return rb_exec_recursive(recursive_eql
, ary1
, ary2
);
2457 recursive_hash(VALUE ary
, VALUE dummy
, int recur
)
2465 h
= RARRAY_LEN(ary
);
2466 for (i
=0; i
<RARRAY_LEN(ary
); i
++) {
2467 h
= (h
<< 1) | (h
<0 ? 1 : 0);
2468 n
= rb_hash(RARRAY_PTR(ary
)[i
]);
2476 * array.hash -> fixnum
2478 * Compute a hash-code for this array. Two arrays with the same content
2479 * will have the same hash code (and will compare using <code>eql?</code>).
2483 rb_ary_hash(VALUE ary
)
2485 return rb_exec_recursive(recursive_hash
, ary
, 0);
2490 * array.include?(obj) -> true or false
2492 * Returns <code>true</code> if the given object is present in
2493 * <i>self</i> (that is, if any object <code>==</code> <i>anObject</i>),
2494 * <code>false</code> otherwise.
2496 * a = [ "a", "b", "c" ]
2497 * a.include?("b") #=> true
2498 * a.include?("z") #=> false
2502 rb_ary_includes(VALUE ary
, VALUE item
)
2506 for (i
=0; i
<RARRAY_LEN(ary
); i
++) {
2507 if (rb_equal(RARRAY_PTR(ary
)[i
], item
)) {
2516 recursive_cmp(VALUE ary1
, VALUE ary2
, int recur
)
2520 if (recur
) return Qnil
;
2521 len
= RARRAY_LEN(ary1
);
2522 if (len
> RARRAY_LEN(ary2
)) {
2523 len
= RARRAY_LEN(ary2
);
2525 for (i
=0; i
<len
; i
++) {
2526 VALUE v
= rb_funcall(rb_ary_elt(ary1
, i
), id_cmp
, 1, rb_ary_elt(ary2
, i
));
2527 if (v
!= INT2FIX(0)) {
2536 * array <=> other_array -> -1, 0, +1
2538 * Comparison---Returns an integer (-1, 0,
2539 * or +1) if this array is less than, equal to, or greater than
2540 * other_array. Each object in each array is compared
2541 * (using <=>). If any value isn't
2542 * equal, then that inequality is the return value. If all the
2543 * values found are equal, then the return is based on a
2544 * comparison of the array lengths. Thus, two arrays are
2545 * ``equal'' according to <code>Array#<=></code> if and only if they have
2546 * the same length and the value of each element is equal to the
2547 * value of the corresponding element in the other array.
2549 * [ "a", "a", "c" ] <=> [ "a", "b", "c" ] #=> -1
2550 * [ 1, 2, 3, 4, 5, 6 ] <=> [ 1, 2 ] #=> +1
2555 rb_ary_cmp(VALUE ary1
, VALUE ary2
)
2560 ary2
= to_ary(ary2
);
2561 if (ary1
== ary2
) return INT2FIX(0);
2562 v
= rb_exec_recursive(recursive_cmp
, ary1
, ary2
);
2563 if (v
!= Qundef
) return v
;
2564 len
= RARRAY_LEN(ary1
) - RARRAY_LEN(ary2
);
2565 if (len
== 0) return INT2FIX(0);
2566 if (len
> 0) return INT2FIX(1);
2571 ary_make_hash(VALUE ary1
, VALUE ary2
)
2573 VALUE hash
= rb_hash_new();
2576 for (i
=0; i
<RARRAY_LEN(ary1
); i
++) {
2577 rb_hash_aset(hash
, RARRAY_PTR(ary1
)[i
], Qtrue
);
2580 for (i
=0; i
<RARRAY_LEN(ary2
); i
++) {
2581 rb_hash_aset(hash
, RARRAY_PTR(ary2
)[i
], Qtrue
);
2589 * array - other_array -> an_array
2591 * Array Difference---Returns a new array that is a copy of
2592 * the original array, removing any items that also appear in
2593 * other_array. (If you need set-like behavior, see the
2594 * library class Set.)
2596 * [ 1, 1, 2, 2, 3, 3, 4, 5 ] - [ 1, 2, 4 ] #=> [ 3, 3, 5 ]
2600 rb_ary_diff(VALUE ary1
, VALUE ary2
)
2603 volatile VALUE hash
;
2606 hash
= ary_make_hash(to_ary(ary2
), 0);
2607 ary3
= rb_ary_new();
2609 for (i
=0; i
<RARRAY_LEN(ary1
); i
++) {
2610 if (st_lookup(RHASH_TBL(hash
), RARRAY_PTR(ary1
)[i
], 0)) continue;
2611 rb_ary_push(ary3
, rb_ary_elt(ary1
, i
));
2618 * array & other_array
2620 * Set Intersection---Returns a new array
2621 * containing elements common to the two arrays, with no duplicates.
2623 * [ 1, 1, 3, 5 ] & [ 1, 2, 3 ] #=> [ 1, 3 ]
2628 rb_ary_and(VALUE ary1
, VALUE ary2
)
2630 VALUE hash
, ary3
, v
, vv
;
2633 ary2
= to_ary(ary2
);
2634 ary3
= rb_ary_new2(RARRAY_LEN(ary1
) < RARRAY_LEN(ary2
) ?
2635 RARRAY_LEN(ary1
) : RARRAY_LEN(ary2
));
2636 hash
= ary_make_hash(ary2
, 0);
2638 if (RHASH_EMPTY_P(hash
))
2641 for (i
=0; i
<RARRAY_LEN(ary1
); i
++) {
2642 v
= vv
= rb_ary_elt(ary1
, i
);
2643 if (st_delete(RHASH_TBL(hash
), (st_data_t
*)&vv
, 0)) {
2644 rb_ary_push(ary3
, v
);
2653 * array | other_array -> an_array
2655 * Set Union---Returns a new array by joining this array with
2656 * other_array, removing duplicates.
2658 * [ "a", "b", "c" ] | [ "c", "d", "a" ]
2659 * #=> [ "a", "b", "c", "d" ]
2663 rb_ary_or(VALUE ary1
, VALUE ary2
)
2669 ary2
= to_ary(ary2
);
2670 ary3
= rb_ary_new2(RARRAY_LEN(ary1
)+RARRAY_LEN(ary2
));
2671 hash
= ary_make_hash(ary1
, ary2
);
2673 for (i
=0; i
<RARRAY_LEN(ary1
); i
++) {
2674 v
= vv
= rb_ary_elt(ary1
, i
);
2675 if (st_delete(RHASH_TBL(hash
), (st_data_t
*)&vv
, 0)) {
2676 rb_ary_push(ary3
, v
);
2679 for (i
=0; i
<RARRAY_LEN(ary2
); i
++) {
2680 v
= vv
= rb_ary_elt(ary2
, i
);
2681 if (st_delete(RHASH_TBL(hash
), (st_data_t
*)&vv
, 0)) {
2682 rb_ary_push(ary3
, v
);
2690 * array.uniq! -> array or nil
2692 * Removes duplicate elements from _self_.
2693 * Returns <code>nil</code> if no changes are made (that is, no
2694 * duplicates are found).
2696 * a = [ "a", "a", "b", "b", "c" ]
2697 * a.uniq! #=> ["a", "b", "c"]
2698 * b = [ "a", "b", "c" ]
2703 rb_ary_uniq_bang(VALUE ary
)
2708 hash
= ary_make_hash(ary
, 0);
2710 if (RARRAY_LEN(ary
) == RHASH_SIZE(hash
)) {
2713 for (i
=j
=0; i
<RARRAY_LEN(ary
); i
++) {
2714 v
= vv
= rb_ary_elt(ary
, i
);
2715 if (st_delete(RHASH_TBL(hash
), (st_data_t
*)&vv
, 0)) {
2716 rb_ary_store(ary
, j
++, v
);
2719 RARRAY(ary
)->len
= j
;
2726 * array.uniq -> an_array
2728 * Returns a new array by removing duplicate values in <i>self</i>.
2730 * a = [ "a", "a", "b", "b", "c" ]
2731 * a.uniq #=> ["a", "b", "c"]
2735 rb_ary_uniq(VALUE ary
)
2737 ary
= rb_ary_dup(ary
);
2738 rb_ary_uniq_bang(ary
);
2744 * array.compact! -> array or nil
2746 * Removes +nil+ elements from array.
2747 * Returns +nil+ if no changes were made.
2749 * [ "a", nil, "b", nil, "c" ].compact! #=> [ "a", "b", "c" ]
2750 * [ "a", "b", "c" ].compact! #=> nil
2754 rb_ary_compact_bang(VALUE ary
)
2760 p
= t
= RARRAY_PTR(ary
);
2761 end
= p
+ RARRAY_LEN(ary
);
2767 n
= p
- RARRAY_PTR(ary
);
2768 if (RARRAY_LEN(ary
) == n
) {
2771 if (n
* 2 < ARY_CAPA(ary
) && ARY_DEFAULT_SIZE
* 2 < ARY_CAPA(ary
)) {
2772 RESIZE_CAPA(ary
, n
* 2);
2774 RARRAY(ary
)->len
= n
;
2781 * array.compact -> an_array
2783 * Returns a copy of _self_ with all +nil+ elements removed.
2785 * [ "a", nil, "b", nil, "c", nil ].compact
2786 * #=> [ "a", "b", "c" ]
2790 rb_ary_compact(VALUE ary
)
2792 ary
= rb_ary_dup(ary
);
2793 rb_ary_compact_bang(ary
);
2799 * array.count -> int
2800 * array.count(obj) -> int
2801 * array.count { |item| block } -> int
2803 * Returns the number of elements. If an argument is given, counts
2804 * the number of elements which equals to <i>obj</i>. If a block is
2805 * given, counts the number of elements yielding a true value.
2807 * ary = [1, 2, 4, 2]
2809 * ary.count(2) # => 2
2810 * ary.count{|x|x%2==0} # => 3
2815 rb_ary_count(int argc
, VALUE
*argv
, VALUE ary
)
2822 if (!rb_block_given_p())
2823 return LONG2NUM(RARRAY_LEN(ary
));
2825 for (p
= RARRAY_PTR(ary
), pend
= p
+ RARRAY_LEN(ary
); p
< pend
; p
++) {
2826 if (RTEST(rb_yield(*p
))) n
++;
2830 VALUE obj
, *p
, *pend
;
2832 rb_scan_args(argc
, argv
, "1", &obj
);
2833 if (rb_block_given_p()) {
2834 rb_warn("given block not used");
2836 for (p
= RARRAY_PTR(ary
), pend
= p
+ RARRAY_LEN(ary
); p
< pend
; p
++) {
2837 if (rb_equal(*p
, obj
)) n
++;
2845 flatten(VALUE ary
, int level
, int *modified
)
2848 VALUE stack
, result
, tmp
, elt
;
2852 stack
= ary_new(0, ARY_DEFAULT_SIZE
);
2853 result
= ary_new(0, RARRAY_LEN(ary
));
2854 memo
= st_init_numtable();
2855 st_insert(memo
, (st_data_t
)ary
, (st_data_t
)Qtrue
);
2859 while (i
< RARRAY_LEN(ary
)) {
2860 elt
= RARRAY_PTR(ary
)[i
++];
2861 tmp
= rb_check_array_type(elt
);
2862 if (RBASIC(result
)->klass
) {
2863 rb_raise(rb_eRuntimeError
, "flatten reentered");
2865 if (NIL_P(tmp
) || (level
>= 0 && RARRAY_LEN(stack
) / 2 >= level
)) {
2866 rb_ary_push(result
, elt
);
2870 id
= (st_data_t
)tmp
;
2871 if (st_lookup(memo
, id
, 0)) {
2872 st_free_table(memo
);
2873 rb_raise(rb_eArgError
, "tried to flatten recursive array");
2875 st_insert(memo
, id
, (st_data_t
)Qtrue
);
2876 rb_ary_push(stack
, ary
);
2877 rb_ary_push(stack
, LONG2NUM(i
));
2882 if (RARRAY_LEN(stack
) == 0) {
2885 id
= (st_data_t
)ary
;
2886 st_delete(memo
, &id
, 0);
2887 tmp
= rb_ary_pop(stack
);
2889 ary
= rb_ary_pop(stack
);
2892 st_free_table(memo
);
2894 RBASIC(result
)->klass
= rb_class_of(ary
);
2900 * array.flatten! -> array or nil
2901 * array.flatten!(level) -> array or nil
2903 * Flattens _self_ in place.
2904 * Returns <code>nil</code> if no modifications were made (i.e.,
2905 * <i>array</i> contains no subarrays.) If the optional <i>level</i>
2906 * argument determines the level of recursion to flatten.
2908 * a = [ 1, 2, [3, [4, 5] ] ]
2909 * a.flatten! #=> [1, 2, 3, 4, 5]
2910 * a.flatten! #=> nil
2911 * a #=> [1, 2, 3, 4, 5]
2912 * a = [ 1, 2, [3, [4, 5] ] ]
2913 * a.flatten!(1) #=> [1, 2, 3, [4, 5]]
2917 rb_ary_flatten_bang(int argc
, VALUE
*argv
, VALUE ary
)
2919 int mod
= 0, level
= -1;
2922 rb_scan_args(argc
, argv
, "01", &lv
);
2923 if (!NIL_P(lv
)) level
= NUM2INT(lv
);
2924 if (level
== 0) return ary
;
2926 result
= flatten(ary
, level
, &mod
);
2927 if (mod
== 0) return Qnil
;
2928 rb_ary_replace(ary
, result
);
2935 * array.flatten -> an_array
2936 * array.flatten(level) -> an_array
2938 * Returns a new array that is a one-dimensional flattening of this
2939 * array (recursively). That is, for every element that is an array,
2940 * extract its elements into the new array. If the optional
2941 * <i>level</i> argument determines the level of recursion to flatten.
2943 * s = [ 1, 2, 3 ] #=> [1, 2, 3]
2944 * t = [ 4, 5, 6, [7, 8] ] #=> [4, 5, 6, [7, 8]]
2945 * a = [ s, t, 9, 10 ] #=> [[1, 2, 3], [4, 5, 6, [7, 8]], 9, 10]
2946 * a.flatten #=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
2947 * a = [ 1, 2, [3, [4, 5] ] ]
2948 * a.flatten(1) #=> [1, 2, 3, [4, 5]]
2952 rb_ary_flatten(int argc
, VALUE
*argv
, VALUE ary
)
2954 int mod
= 0, level
= -1;
2957 rb_scan_args(argc
, argv
, "01", &lv
);
2958 if (!NIL_P(lv
)) level
= NUM2INT(lv
);
2959 if (level
== 0) return ary
;
2961 result
= flatten(ary
, level
, &mod
);
2962 OBJ_INFECT(result
, ary
);
2969 * array.shuffle! -> array
2971 * Shuffles elements in _self_ in place.
2976 rb_ary_shuffle_bang(VALUE ary
)
2978 long i
= RARRAY_LEN(ary
);
2982 long j
= rb_genrand_real()*i
;
2983 VALUE tmp
= RARRAY_PTR(ary
)[--i
];
2984 RARRAY_PTR(ary
)[i
] = RARRAY_PTR(ary
)[j
];
2985 RARRAY_PTR(ary
)[j
] = tmp
;
2993 * array.shuffle -> an_array
2995 * Returns a new array with elements of this array shuffled.
2997 * a = [ 1, 2, 3 ] #=> [1, 2, 3]
2998 * a.shuffle #=> [2, 3, 1]
3002 rb_ary_shuffle(VALUE ary
)
3004 ary
= rb_ary_dup(ary
);
3005 rb_ary_shuffle_bang(ary
);
3012 * array.sample -> obj
3013 * array.sample(n) -> an_array
3015 * Choose a random element, or the random +n+ elements, fron the array.
3016 * If the array is empty, the first form returns <code>nil</code>, and the
3017 * second form returns an empty array.
3023 rb_ary_sample(int argc
, VALUE
*argv
, VALUE ary
)
3028 len
= RARRAY_LEN(ary
);
3030 if (len
== 0) return Qnil
;
3031 i
= rb_genrand_real()*len
;
3032 return RARRAY_PTR(ary
)[i
];
3034 rb_scan_args(argc
, argv
, "1", &nv
);
3035 if (len
== 0) return rb_ary_new2(0);
3037 result
= rb_ary_new2(n
);
3038 for (i
=0; i
<n
; i
++) {
3040 j
= rb_genrand_real()*len
;
3042 for (j
=0; j
<i
; j
++) {
3043 if (RARRAY_PTR(result
)[j
] == nv
)
3046 RARRAY_PTR(result
)[i
] = nv
;
3047 ARY_SET_LEN(result
, i
+1);
3049 for (i
=0; i
<n
; i
++) {
3050 nv
= RARRAY_PTR(result
)[i
];
3051 RARRAY_PTR(result
)[i
] = RARRAY_PTR(ary
)[NUM2LONG(nv
)];
3059 * ary.cycle {|obj| block }
3060 * ary.cycle(n) {|obj| block }
3062 * Calls <i>block</i> for each element repeatedly _n_ times or
3063 * forever if none or nil is given. If a non-positive number is
3064 * given or the array is empty, does nothing. Returns nil if the
3065 * loop has finished without getting interrupted.
3067 * a = ["a", "b", "c"]
3068 * a.cycle {|x| puts x } # print, a, b, c, a, b, c,.. forever.
3069 * a.cycle(2) {|x| puts x } # print, a, b, c, a, b, c.
3074 rb_ary_cycle(int argc
, VALUE
*argv
, VALUE ary
)
3079 rb_scan_args(argc
, argv
, "01", &nv
);
3081 RETURN_ENUMERATOR(ary
, argc
, argv
);
3087 if (n
<= 0) return Qnil
;
3090 while (RARRAY_LEN(ary
) > 0 && (n
< 0 || 0 < n
--)) {
3091 for (i
=0; i
<RARRAY_LEN(ary
); i
++) {
3092 rb_yield(RARRAY_PTR(ary
)[i
]);
3098 #define tmpbuf(n, size) rb_str_tmp_new((n)*(size))
3101 * Recursively compute permutations of r elements of the set [0..n-1].
3102 * When we have a complete permutation of array indexes, copy the values
3103 * at those indexes into a new array and yield that array.
3105 * n: the size of the set
3106 * r: the number of elements in each permutation
3107 * p: the array (of size r) that we're filling in
3108 * index: what index we're filling in now
3109 * used: an array of booleans: whether a given index is already used
3110 * values: the Ruby array that holds the actual values to permute
3113 permute0(long n
, long r
, long *p
, long index
, int *used
, VALUE values
)
3116 for (i
= 0; i
< n
; i
++) {
3119 if (index
< r
-1) { /* if not done yet */
3120 used
[i
] = 1; /* mark index used */
3121 permute0(n
, r
, p
, index
+1, /* recurse */
3123 used
[i
] = 0; /* index unused */
3126 /* We have a complete permutation of array indexes */
3127 /* Build a ruby array of the corresponding values */
3128 /* And yield it to the associated block */
3129 VALUE result
= rb_ary_new2(r
);
3130 VALUE
*result_array
= RARRAY_PTR(result
);
3131 const VALUE
*values_array
= RARRAY_PTR(values
);
3133 for (j
= 0; j
< r
; j
++) result_array
[j
] = values_array
[p
[j
]];
3134 RARRAY(result
)->len
= r
;
3143 * ary.permutation { |p| block } -> array
3144 * ary.permutation -> enumerator
3145 * ary.permutation(n) { |p| block } -> array
3146 * ary.permutation(n) -> enumerator
3148 * When invoked with a block, yield all permutations of length <i>n</i>
3149 * of the elements of <i>ary</i>, then return the array itself.
3150 * If <i>n</i> is not specified, yield all permutations of all elements.
3151 * The implementation makes no guarantees about the order in which
3152 * the permutations are yielded.
3154 * When invoked without a block, return an enumerator object instead.
3159 * a.permutation.to_a #=> [[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
3160 * a.permutation(1).to_a #=> [[1],[2],[3]]
3161 * a.permutation(2).to_a #=> [[1,2],[1,3],[2,1],[2,3],[3,1],[3,2]]
3162 * a.permutation(3).to_a #=> [[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
3163 * a.permutation(0).to_a #=> [[]] # one permutation of length 0
3164 * a.permutation(4).to_a #=> [] # no permutations of length 4
3168 rb_ary_permutation(int argc
, VALUE
*argv
, VALUE ary
)
3173 n
= RARRAY_LEN(ary
); /* Array length */
3174 RETURN_ENUMERATOR(ary
, argc
, argv
); /* Return enumerator if no block */
3175 rb_scan_args(argc
, argv
, "01", &num
);
3176 r
= NIL_P(num
) ? n
: NUM2LONG(num
); /* Permutation size from argument */
3178 if (r
< 0 || n
< r
) {
3179 /* no permutations: yield nothing */
3181 else if (r
== 0) { /* exactly one permutation: the zero-length array */
3182 rb_yield(rb_ary_new2(0));
3184 else if (r
== 1) { /* this is a special, easy case */
3185 for (i
= 0; i
< RARRAY_LEN(ary
); i
++) {
3186 rb_yield(rb_ary_new3(1, RARRAY_PTR(ary
)[i
]));
3189 else { /* this is the general case */
3190 volatile VALUE t0
= tmpbuf(n
,sizeof(long));
3191 long *p
= (long*)RSTRING_PTR(t0
);
3192 volatile VALUE t1
= tmpbuf(n
,sizeof(int));
3193 int *used
= (int*)RSTRING_PTR(t1
);
3194 VALUE ary0
= ary_make_shared(ary
); /* private defensive copy of ary */
3196 for (i
= 0; i
< n
; i
++) used
[i
] = 0; /* initialize array */
3198 permute0(n
, r
, p
, 0, used
, ary0
); /* compute and yield permutations */
3206 combi_len(long n
, long k
)
3210 if (k
*2 > n
) k
= n
-k
;
3211 if (k
== 0) return 1;
3212 if (k
< 0) return 0;
3214 for (i
=1; i
<= k
; i
++,n
--) {
3218 rb_raise(rb_eRangeError
, "too big for combination");
3227 * ary.combination(n) { |c| block } -> ary
3228 * ary.combination(n) -> enumerator
3230 * When invoked with a block, yields all combinations of length <i>n</i>
3231 * of elements from <i>ary</i> and then returns <i>ary</i> itself.
3232 * The implementation makes no guarantees about the order in which
3233 * the combinations are yielded.
3235 * When invoked without a block, returns an enumerator object instead.
3240 * a.combination(1).to_a #=> [[1],[2],[3],[4]]
3241 * a.combination(2).to_a #=> [[1,2],[1,3],[1,4],[2,3],[2,4],[3,4]]
3242 * a.combination(3).to_a #=> [[1,2,3],[1,2,4],[1,3,4],[2,3,4]]
3243 * a.combination(4).to_a #=> [[1,2,3,4]]
3244 * a.combination(0).to_a #=> [[]] # one combination of length 0
3245 * a.combination(5).to_a #=> [] # no combinations of length 5
3250 rb_ary_combination(VALUE ary
, VALUE num
)
3255 RETURN_ENUMERATOR(ary
, 1, &num
);
3256 len
= RARRAY_LEN(ary
);
3257 if (n
< 0 || len
< n
) {
3261 rb_yield(rb_ary_new2(0));
3264 for (i
= 0; i
< len
; i
++) {
3265 rb_yield(rb_ary_new3(1, RARRAY_PTR(ary
)[i
]));
3269 volatile VALUE t0
= tmpbuf(n
+1, sizeof(long));
3270 long *stack
= (long*)RSTRING_PTR(t0
);
3271 long nlen
= combi_len(len
, n
);
3272 volatile VALUE cc
= rb_ary_new2(n
);
3273 VALUE
*chosen
= RARRAY_PTR(cc
);
3276 RBASIC(cc
)->klass
= 0;
3277 MEMZERO(stack
, long, n
);
3279 for (i
= 0; i
< nlen
; i
++) {
3280 chosen
[lev
] = RARRAY_PTR(ary
)[stack
[lev
+1]];
3281 for (lev
++; lev
< n
; lev
++) {
3282 chosen
[lev
] = RARRAY_PTR(ary
)[stack
[lev
+1] = stack
[lev
]+1];
3284 rb_yield(rb_ary_new4(n
, chosen
));
3287 } while (lev
&& (stack
[lev
+1]+n
== len
+lev
+1));
3295 * ary.product(other_ary, ...)
3297 * Returns an array of all combinations of elements from all arrays.
3298 * The length of the returned array is the product of the length
3299 * of ary and the argument arrays
3301 * [1,2,3].product([4,5]) # => [[1,4],[1,5],[2,4],[2,5],[3,4],[3,5]]
3302 * [1,2].product([1,2]) # => [[1,1],[1,2],[2,1],[2,2]]
3303 * [1,2].product([3,4],[5,6]) # => [[1,3,5],[1,3,6],[1,4,5],[1,4,6],
3304 * # [2,3,5],[2,3,6],[2,4,5],[2,4,6]]
3305 * [1,2].product() # => [[1],[2]]
3306 * [1,2].product([]) # => []
3310 rb_ary_product(int argc
, VALUE
*argv
, VALUE ary
)
3312 int n
= argc
+1; /* How many arrays we're operating on */
3313 volatile VALUE t0
= tmpbuf(n
, sizeof(VALUE
));
3314 volatile VALUE t1
= tmpbuf(n
, sizeof(int));
3315 VALUE
*arrays
= (VALUE
*)RSTRING_PTR(t0
); /* The arrays we're computing the product of */
3316 int *counters
= (int*)RSTRING_PTR(t1
); /* The current position in each one */
3317 VALUE result
; /* The array we'll be returning */
3321 RBASIC(t0
)->klass
= 0;
3322 RBASIC(t1
)->klass
= 0;
3324 /* initialize the arrays of arrays */
3326 for (i
= 1; i
< n
; i
++) arrays
[i
] = to_ary(argv
[i
-1]);
3328 /* initialize the counters for the arrays */
3329 for (i
= 0; i
< n
; i
++) counters
[i
] = 0;
3331 /* Compute the length of the result array; return [] if any is empty */
3332 for (i
= 0; i
< n
; i
++) {
3333 long k
= RARRAY_LEN(arrays
[i
]), l
= resultlen
;
3334 if (k
== 0) return rb_ary_new2(0);
3336 if (resultlen
< k
|| resultlen
< l
|| resultlen
/ k
!= l
) {
3337 rb_raise(rb_eRangeError
, "too big to product");
3341 /* Otherwise, allocate and fill in an array of results */
3342 result
= rb_ary_new2(resultlen
);
3343 for (i
= 0; i
< resultlen
; i
++) {
3345 /* fill in one subarray */
3346 VALUE subarray
= rb_ary_new2(n
);
3347 for (j
= 0; j
< n
; j
++) {
3348 rb_ary_push(subarray
, rb_ary_entry(arrays
[j
], counters
[j
]));
3351 /* put it on the result array */
3352 rb_ary_push(result
, subarray
);
3355 * Increment the last counter. If it overflows, reset to 0
3356 * and increment the one before it.
3360 while (m
> 0 && counters
[m
] == RARRAY_LEN(arrays
[m
])) {
3372 * ary.take(n) => array
3374 * Returns first n elements from <i>ary</i>.
3376 * a = [1, 2, 3, 4, 5, 0]
3377 * a.take(3) # => [1, 2, 3]
3382 rb_ary_take(VALUE obj
, VALUE n
)
3384 long len
= NUM2LONG(n
);
3386 rb_raise(rb_eArgError
, "attempt to take negative size");
3388 return rb_ary_subseq(obj
, 0, len
);
3393 * ary.take_while {|arr| block } => array
3395 * Passes elements to the block until the block returns nil or false,
3396 * then stops iterating and returns an array of all prior elements.
3398 * a = [1, 2, 3, 4, 5, 0]
3399 * a.take_while {|i| i < 3 } # => [1, 2]
3404 rb_ary_take_while(VALUE ary
)
3408 RETURN_ENUMERATOR(ary
, 0, 0);
3409 for (i
= 0; i
< RARRAY_LEN(ary
); i
++) {
3410 if (!RTEST(rb_yield(RARRAY_PTR(ary
)[i
]))) break;
3412 return rb_ary_take(ary
, LONG2FIX(i
));
3417 * ary.drop(n) => array
3419 * Drops first n elements from <i>ary</i>, and returns rest elements
3422 * a = [1, 2, 3, 4, 5, 0]
3423 * a.drop(3) # => [4, 5, 0]
3428 rb_ary_drop(VALUE ary
, VALUE n
)
3431 long pos
= NUM2LONG(n
);
3433 rb_raise(rb_eArgError
, "attempt to drop negative size");
3436 result
= rb_ary_subseq(ary
, pos
, RARRAY_LEN(ary
));
3437 if (result
== Qnil
) result
= rb_ary_new();
3443 * ary.drop_while {|arr| block } => array
3445 * Drops elements up to, but not including, the first element for
3446 * which the block returns nil or false and returns an array
3447 * containing the remaining elements.
3449 * a = [1, 2, 3, 4, 5, 0]
3450 * a.drop_while {|i| i < 3 } # => [3, 4, 5, 0]
3455 rb_ary_drop_while(VALUE ary
)
3459 RETURN_ENUMERATOR(ary
, 0, 0);
3460 for (i
= 0; i
< RARRAY_LEN(ary
); i
++) {
3461 if (!RTEST(rb_yield(RARRAY_PTR(ary
)[i
]))) break;
3463 return rb_ary_drop(ary
, LONG2FIX(i
));
3468 /* Arrays are ordered, integer-indexed collections of any object.
3469 * Array indexing starts at 0, as in C or Java. A negative index is
3470 * assumed to be relative to the end of the array---that is, an index of -1
3471 * indicates the last element of the array, -2 is the next to last
3472 * element in the array, and so on.
3480 rb_cArray
= rb_define_class("Array", rb_cObject
);
3481 rb_include_module(rb_cArray
, rb_mEnumerable
);
3483 rb_define_alloc_func(rb_cArray
, ary_alloc
);
3484 rb_define_singleton_method(rb_cArray
, "[]", rb_ary_s_create
, -1);
3485 rb_define_singleton_method(rb_cArray
, "try_convert", rb_ary_s_try_convert
, 1);
3486 rb_define_method(rb_cArray
, "initialize", rb_ary_initialize
, -1);
3487 rb_define_method(rb_cArray
, "initialize_copy", rb_ary_replace
, 1);
3489 rb_define_method(rb_cArray
, "to_s", rb_ary_inspect
, 0);
3490 rb_define_method(rb_cArray
, "inspect", rb_ary_inspect
, 0);
3491 rb_define_method(rb_cArray
, "to_a", rb_ary_to_a
, 0);
3492 rb_define_method(rb_cArray
, "to_ary", rb_ary_to_ary_m
, 0);
3493 rb_define_method(rb_cArray
, "frozen?", rb_ary_frozen_p
, 0);
3495 rb_define_method(rb_cArray
, "==", rb_ary_equal
, 1);
3496 rb_define_method(rb_cArray
, "eql?", rb_ary_eql
, 1);
3497 rb_define_method(rb_cArray
, "hash", rb_ary_hash
, 0);
3499 rb_define_method(rb_cArray
, "[]", rb_ary_aref
, -1);
3500 rb_define_method(rb_cArray
, "[]=", rb_ary_aset
, -1);
3501 rb_define_method(rb_cArray
, "at", rb_ary_at
, 1);
3502 rb_define_method(rb_cArray
, "fetch", rb_ary_fetch
, -1);
3503 rb_define_method(rb_cArray
, "first", rb_ary_first
, -1);
3504 rb_define_method(rb_cArray
, "last", rb_ary_last
, -1);
3505 rb_define_method(rb_cArray
, "concat", rb_ary_concat
, 1);
3506 rb_define_method(rb_cArray
, "<<", rb_ary_push
, 1);
3507 rb_define_method(rb_cArray
, "push", rb_ary_push_m
, -1);
3508 rb_define_method(rb_cArray
, "pop", rb_ary_pop_m
, -1);
3509 rb_define_method(rb_cArray
, "shift", rb_ary_shift_m
, -1);
3510 rb_define_method(rb_cArray
, "unshift", rb_ary_unshift_m
, -1);
3511 rb_define_method(rb_cArray
, "insert", rb_ary_insert
, -1);
3512 rb_define_method(rb_cArray
, "each", rb_ary_each
, 0);
3513 rb_define_method(rb_cArray
, "each_index", rb_ary_each_index
, 0);
3514 rb_define_method(rb_cArray
, "reverse_each", rb_ary_reverse_each
, 0);
3515 rb_define_method(rb_cArray
, "length", rb_ary_length
, 0);
3516 rb_define_alias(rb_cArray
, "size", "length");
3517 rb_define_method(rb_cArray
, "empty?", rb_ary_empty_p
, 0);
3518 rb_define_method(rb_cArray
, "find_index", rb_ary_index
, -1);
3519 rb_define_method(rb_cArray
, "index", rb_ary_index
, -1);
3520 rb_define_method(rb_cArray
, "rindex", rb_ary_rindex
, -1);
3521 rb_define_method(rb_cArray
, "join", rb_ary_join_m
, -1);
3522 rb_define_method(rb_cArray
, "reverse", rb_ary_reverse_m
, 0);
3523 rb_define_method(rb_cArray
, "reverse!", rb_ary_reverse_bang
, 0);
3524 rb_define_method(rb_cArray
, "sort", rb_ary_sort
, 0);
3525 rb_define_method(rb_cArray
, "sort!", rb_ary_sort_bang
, 0);
3526 rb_define_method(rb_cArray
, "collect", rb_ary_collect
, 0);
3527 rb_define_method(rb_cArray
, "collect!", rb_ary_collect_bang
, 0);
3528 rb_define_method(rb_cArray
, "map", rb_ary_collect
, 0);
3529 rb_define_method(rb_cArray
, "map!", rb_ary_collect_bang
, 0);
3530 rb_define_method(rb_cArray
, "select", rb_ary_select
, 0);
3531 rb_define_method(rb_cArray
, "values_at", rb_ary_values_at
, -1);
3532 rb_define_method(rb_cArray
, "delete", rb_ary_delete
, 1);
3533 rb_define_method(rb_cArray
, "delete_at", rb_ary_delete_at_m
, 1);
3534 rb_define_method(rb_cArray
, "delete_if", rb_ary_delete_if
, 0);
3535 rb_define_method(rb_cArray
, "reject", rb_ary_reject
, 0);
3536 rb_define_method(rb_cArray
, "reject!", rb_ary_reject_bang
, 0);
3537 rb_define_method(rb_cArray
, "zip", rb_ary_zip
, -1);
3538 rb_define_method(rb_cArray
, "transpose", rb_ary_transpose
, 0);
3539 rb_define_method(rb_cArray
, "replace", rb_ary_replace
, 1);
3540 rb_define_method(rb_cArray
, "clear", rb_ary_clear
, 0);
3541 rb_define_method(rb_cArray
, "fill", rb_ary_fill
, -1);
3542 rb_define_method(rb_cArray
, "include?", rb_ary_includes
, 1);
3543 rb_define_method(rb_cArray
, "<=>", rb_ary_cmp
, 1);
3545 rb_define_method(rb_cArray
, "slice", rb_ary_aref
, -1);
3546 rb_define_method(rb_cArray
, "slice!", rb_ary_slice_bang
, -1);
3548 rb_define_method(rb_cArray
, "assoc", rb_ary_assoc
, 1);
3549 rb_define_method(rb_cArray
, "rassoc", rb_ary_rassoc
, 1);
3551 rb_define_method(rb_cArray
, "+", rb_ary_plus
, 1);
3552 rb_define_method(rb_cArray
, "*", rb_ary_times
, 1);
3554 rb_define_method(rb_cArray
, "-", rb_ary_diff
, 1);
3555 rb_define_method(rb_cArray
, "&", rb_ary_and
, 1);
3556 rb_define_method(rb_cArray
, "|", rb_ary_or
, 1);
3558 rb_define_method(rb_cArray
, "uniq", rb_ary_uniq
, 0);
3559 rb_define_method(rb_cArray
, "uniq!", rb_ary_uniq_bang
, 0);
3560 rb_define_method(rb_cArray
, "compact", rb_ary_compact
, 0);
3561 rb_define_method(rb_cArray
, "compact!", rb_ary_compact_bang
, 0);
3562 rb_define_method(rb_cArray
, "flatten", rb_ary_flatten
, -1);
3563 rb_define_method(rb_cArray
, "flatten!", rb_ary_flatten_bang
, -1);
3564 rb_define_method(rb_cArray
, "count", rb_ary_count
, -1);
3565 rb_define_method(rb_cArray
, "shuffle!", rb_ary_shuffle_bang
, 0);
3566 rb_define_method(rb_cArray
, "shuffle", rb_ary_shuffle
, 0);
3567 rb_define_method(rb_cArray
, "sample", rb_ary_sample
, -1);
3568 rb_define_method(rb_cArray
, "cycle", rb_ary_cycle
, -1);
3569 rb_define_method(rb_cArray
, "permutation", rb_ary_permutation
, -1);
3570 rb_define_method(rb_cArray
, "combination", rb_ary_combination
, 1);
3571 rb_define_method(rb_cArray
, "product", rb_ary_product
, -1);
3573 rb_define_method(rb_cArray
, "take", rb_ary_take
, 1);
3574 rb_define_method(rb_cArray
, "take_while", rb_ary_take_while
, 0);
3575 rb_define_method(rb_cArray
, "drop", rb_ary_drop
, 1);
3576 rb_define_method(rb_cArray
, "drop_while", rb_ary_drop_while
, 0);
3578 id_cmp
= rb_intern("<=>");