This is a multi-part message in MIME format.
--------------020509020403000302000408
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit

Nobuyoshi Nakada wrote:
> At Fri, 16 Nov 2007 18:47:50 +0900,
> murphy wrote in [ruby-core:13597]:
>> +VALUE
>> +rb_ary_split_at(int argc, VALUE *argv, VALUE ary)
>> +{
>> +    return Qnil;
> 
> What's this?
debugging artifacts, makes me look stupid. I misinterpreted the output
of "make test". sorry.

>> +    long pos, len;
>> +    len  ;  /* default */
> 
>> +    VALUE left   ry_shared_array(rb_cArray, ary);
>> +    VALUE right  ry_shared_array(rb_cArray, ary);
> 
> These need C99.
you mean, declare them at the top of the function? okay.

> 
>> +    RARRAY(left)->len  os;
>> +    RARRAY(right)->ptr + os + len;
>> +    RARRAY(right)->len + ARRAY_LEN(ary) - (pos + len);
> 
> The last assignment shouldn't be:
> +    RARRAY(right)->len - os + len;
> or
> +    RARRAY(right)->len  ARRAY_LEN(ary) - (pos + len);
> ?
> 
I found another bug and rewrote this section. thank you.

the tests should now run for real.
[murphy]

--------------020509020403000302000408
Content-Type: text/plain; x-mac-type="0"; x-mac-creator="0";
 name
rray_split_at_draft_2.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename
rray_split_at_draft_2.diff"

Index: array.c
--- array.c	(revision 13948)
+++ array.c	(working copy)
@@ -781,6 +781,75 @@
     return rb_ary_entry(ary, NUM2LONG(pos));
 }
 
+/* 
+ *  call-seq:
+ *     array.split_at(index)          -> [left_array, right_array]
+ *     array.split_at(start, length)  -> [left_array, right_array]
+ *
+ *  Splits an array into two parts, with the first one containing
+ *  all elements before the given range, and the second one containing
+ *  all elements after it.
+ * 
+ *     a   "a", "b", "c", "d", "e" ]
+ *     a.split_at(0)          #[[], ["b", "c", "d", "e"]]
+ *     a.split_at(2)          #[["a", "b"], ["d", "e"]]
+ *     a.split_at(-1)         #[["a", "b", "c", "d"], []]
+ *     a.split_at(1, 2)       #[["a"], ["d", "e"]]
+ *     a.split_at(1, 0)       #[["a"], ["b", "c", "d", "e"]]
+ *  
+ */
+
+VALUE
+rb_ary_split_at(int argc, VALUE *argv, VALUE ary)
+{
+    long pos, len;
+    VALUE left, right;
+    len  ;  /* default */
+    
+    switch (argc) {
+      case 2:
+	len  UM2LONG(argv[1]);
+	/* fall through */
+      case 1:
+	pos  UM2LONG(argv[0]);
+	break;
+      default:
+	rb_scan_args(argc, argv, "11", 0, 0);
+    }
+    
+    if (RARRAY_LEN(ary) 0) {
+	return rb_assoc_new(rb_ary_new2(0), rb_ary_new2(0));
+    }
+    
+    if (pos < 0) {
+	pos + ARRAY_LEN(ary);
+    }
+    
+    /* pos out of bounds? */
+    if (pos < 0) {
+	return rb_assoc_new(rb_ary_new2(0), ary_shared_array(rb_cArray, ary));
+    }
+    
+    /* Array#slice doesn't fail on negative lengths, so we copy */
+    if (len < 0) {
+	len  ;
+    }
+    
+    left   ry_shared_array(rb_cArray, ary);
+    RARRAY(left)->len  os;
+    
+    /* pos+len out of bounds? */
+    if (pos + len > RARRAY_LEN(ary)) {
+	return rb_assoc_new(left, rb_ary_new2(0));
+    }
+    
+    right  ry_shared_array(rb_cArray, ary);
+    RARRAY(right)->ptr + os + len;
+    RARRAY(right)->len - os + len;
+    
+    return rb_assoc_new(left, right);
+}
+
 /*
  *  call-seq:
  *     array.first     ->   obj or nil
@@ -2557,7 +2626,7 @@
     hash  ry_make_hash(ary2, 0);
 
     if (RHASH_EMPTY_P(hash))
-        return ary3;
+	return ary3;
 
     for (i i<RARRAY_LEN(ary1); i++) {
 	v  v  b_ary_elt(ary1, i);
@@ -3288,6 +3357,7 @@
 
     rb_define_method(rb_cArray, "slice", rb_ary_aref, -1);
     rb_define_method(rb_cArray, "slice!", rb_ary_slice_bang, -1);
+    rb_define_method(rb_cArray, "split_at", rb_ary_split_at, -1);
 
     rb_define_method(rb_cArray, "assoc", rb_ary_assoc, 1);
     rb_define_method(rb_cArray, "rassoc", rb_ary_rassoc, 1);

--------------020509020403000302000408--