[Bug #3708]

どうもarrayが共有中におきるみたいです。1.8でもおきました。

% ruby -v -e  "o=[0,1,2,3,4,5][1,4];p o;p o.permutation.to_a"
ruby 1.9.3dev (2010-08-12 trunk 28970) [powerpc-aix5.3.0.0]
[1, 2, 3, 4]
[[0, 1, 2, 3], [0, 1, 3, 2], [0, 2, 1, 3], [0, 2, 3, 1], [0, 3, 1, 2], [0, 3, 2, 1], [1, 0, 2, 3], [1, 0, 3, 2], [1, 2, 0, 3], [1, 2, 3, 0], [1, 3, 0, 2], [1, 3, 2, 0], [2, 0, 1, 3], [2, 0, 3, 1], [2, 1, 0, 3], [2, 1, 3, 0], [2, 3, 0, 1], [2, 3, 1, 0], [3, 0, 1, 2], [3, 0, 2, 1], [3, 1, 0, 2], [3, 1, 2, 0], [3, 2, 0, 1], [3, 2, 1, 0]]

% ruby -v -e  "o=[0,1,2,3,4,5][1,4];p o;o[0]=1;p o.permutation.to_a"
ruby 1.9.3dev (2010-08-12 trunk 28970) [powerpc-aix5.3.0.0]
[1, 2, 3, 4]
[[1, 2, 3, 4], [1, 2, 4, 3], [1, 3, 2, 4], [1, 3, 4, 2], [1, 4, 2, 3], [1, 4, 3, 2], [2, 1, 3, 4], [2, 1, 4, 3], [2, 3, 1, 4], [2, 3, 4, 1], [2, 4, 1, 3], [2, 4, 3, 1], [3, 1, 2, 4], [3, 1, 4, 2], [3, 2, 1, 4], [3, 2, 4, 1], [3, 4, 1, 2], [3, 4, 2, 1], [4, 1, 2, 3], [4, 1, 3, 2], [4, 2, 1, 3], [4, 2, 3, 1], [4, 3, 1, 2], [4, 3, 2, 1]] 

追記:そういうことなんですか。あとちょっと。精進しましょう。
追記2: segvするらしい。
追記3: ary_make_partialで一部を共有するやつを、rb_ary_permutationの中でary_make_substitutionしてもういっこshareしたときに、オリジナルの方をみちゃうのかな。
追記4: ary_make_shared_copyでコピーすればオッケーな模様。勉強になった。
追記5: まったく持って自信がないけど1.8用。同じようなことができる関数がない気がしたので、適当にでっち上げた。こういうのはメンテナがすきにするところだな。

% svn diff
Index: array.c
===================================================================
--- array.c     (リビジョン 29036)
+++ array.c     (作業コピー)
@@ -768,6 +768,13 @@
     return ary2;
 }

+static VALUE
+rb_ary_shared_copy(ary)
+    VALUE ary;
+{
+  return rb_ary_subseq(ary, 0, RARRAY(ary)->len);
+}
+
 /*
  *  call-seq:
  *     array[index]                -> obj      or nil
@@ -3558,7 +3565,7 @@
        long *p = (long*)RSTRING(t0)->ptr;
        volatile VALUE t1 = tmpbuf(n,sizeof(int));
        int *used = (int*)RSTRING(t1)->ptr;
-       VALUE ary0 = ary_make_shared(ary); /* private defensive copy of ary */
+       VALUE ary0 = rb_ary_shared_copy(ary); /* private defensive copy of ary */

        for (i = 0; i < n; i++) used[i] = 0; /* initialize array */

Index: test/ruby/test_array.rb
===================================================================
--- test/ruby/test_array.rb     (リビジョン 29036)
+++ test/ruby/test_array.rb     (作業コピー)
@@ -1255,6 +1255,8 @@
                  "edcba".each_char.to_a.permutation(5).sort)
     assert_equal(@cls[].permutation(0).to_a, @cls[[]])

+    assert_equal(@cls[1,2,3,4].permutation.to_a,
+                 @cls[0,1,2,3,4][1,4].permutation.to_a);
   end

   def test_take