public Method

Array.fill(...)

array.fill(obj)                                 array
array.fill(obj, start [, length])               array
array.fill(obj, range )                         array
array.fill {|index| block }                     array
array.fill(start [, length] ) {|index| block }  array
array.fill(range) {|index| block }              array

The first three forms set the selected elements of self (which may be the entire array) to obj. A start of nil is equivalent to zero. A length of nil is equivalent to self.length. The last three forms fill the array with the value of the block. The block is passed the absolute index of each element to be filled.

a = [ "a", "b", "c", "d" ]
a.fill("x")              #=> ["x", "x", "x", "x"]
a.fill("z", 2, 2)        #=> ["x", "x", "z", "z"]
a.fill("y", 0..1)        #=> ["y", "y", "z", "z"]
a.fill {|i| i*i}         #=> [0, 1, 4, 9]
a.fill(-2) {|i| i*i*i}   #=> [0, 1, 8, 27]

Source Code

/*
*  call-seq:
*     array.fill(obj)                                -> array
*     array.fill(obj, start [, length])              -> array
*     array.fill(obj, range )                        -> array
*     array.fill {|index| block }                    -> array
*     array.fill(start [, length] ) {|index| block } -> array
*     array.fill(range) {|index| block }             -> array
*  
*  The first three forms set the selected elements of <i>self</i> (which
*  may be the entire array) to <i>obj</i>. A <i>start</i> of
*  <code>nil</code> is equivalent to zero. A <i>length</i> of
*  <code>nil</code> is equivalent to <i>self.length</i>. The last three
*  forms fill the array with the value of the block. The block is
*  passed the absolute index of each element to be filled.
*     
*     a = [ "a", "b", "c", "d" ]
*     a.fill("x")              #=> ["x", "x", "x", "x"]
*     a.fill("z", 2, 2)        #=> ["x", "x", "z", "z"]
*     a.fill("y", 0..1)        #=> ["y", "y", "z", "z"]
*     a.fill {|i| i*i}         #=> [0, 1, 4, 9]
*     a.fill(-2) {|i| i*i*i}   #=> [0, 1, 8, 27]
*/

static VALUE
rb_ary_fill(argc, argv, ary)
   int argc;
   VALUE *argv;
   VALUE ary;
{
   VALUE item, arg1, arg2;
   long beg = 0, end = 0, len = 0;
   VALUE *p, *pend;
   int block_p = Qfalse;

   if (rb_block_given_p()) {
       block_p = Qtrue;
       rb_scan_args(argc, argv, "02", &arg1, &arg2);
       argc += 1;             /* hackish */
   }
   else {
       rb_scan_args(argc, argv, "12", &item, &arg1, &arg2);
   }
   switch (argc) {
     case 1:
       beg = 0;
       len = RARRAY(ary)->len;
       break;
     case 2:
       if (rb_range_beg_len(arg1, &beg, &len, RARRAY(ary)->len, 1)) {
           break;
       }
       /* fall through */
     case 3:
       beg = NIL_P(arg1) ? 0 : NUM2LONG(arg1);
       if (beg < 0) {
           beg = RARRAY(ary)->len + beg;
           if (beg < 0) beg = 0;
       }
       len = NIL_P(arg2) ? RARRAY(ary)->len - beg : NUM2LONG(arg2);
       break;
   }
   rb_ary_modify(ary);
   end = beg + len;
   if (end < 0) {
       rb_raise(rb_eArgError, "argument too big");
   }
   if (end > RARRAY(ary)->len) {
       if (end >= RARRAY(ary)->aux.capa) {
           REALLOC_N(RARRAY(ary)->ptr, VALUE, end);
           RARRAY(ary)->aux.capa = end;
       }
       rb_mem_clear(RARRAY(ary)->ptr + RARRAY(ary)->len, end - RARRAY(ary)->len);
       RARRAY(ary)->len = end;
   }

   if (block_p) {
       VALUE v;
       long i;

       for (i=beg; i<end; i++) {
           v = rb_yield(LONG2NUM(i));
           if (i>=RARRAY(ary)->len) break;
           RARRAY(ary)->ptr[i] = v;
       }
   }
   else {
       p = RARRAY(ary)->ptr + beg;
       pend = p + len;
       while (p < pend) {
           *p++ = item;
       }
   }
   return ary;
}
Comments

Have your say
Please use Textile formatting (click here for a cheat sheet). Use <code/> and <pre/> for code samples.
Click here to login with OpenID to to post comments.