From: Kenta Murata Date: 2010-08-18T18:16:13+09:00 Subject: [ruby-dev:42068] Re: [Bug #3708] Array#permutation がおかしな結果を返す むらたです。 On 2010/08/18, at 16:33, Shumpei Akai wrote: > Array#permutationの結果に,配列に含まれていないはずの値が入っています > > % ./ruby_head -e "p [0,1,2,3,4][1,4].permutation.to_a" > [[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]] > > > [0,1,2,3,4][1,4] は [1, 2, 3, 4] なので0は含まれないはずです. > > > % ./ruby_head -e "p [0,1,2,3][1,3].permutation.to_a" > だと正しく動きます ary_make_shared 関数を以下のように修正すると正常に動作します。 diff --git a/array.c b/array.c index 51d3ad2..ea4fe43 100644 --- a/array.c +++ b/array.c @@ -409,10 +409,7 @@ static VALUE ary_make_shared(VALUE ary) { assert(!ARY_EMBED_P(ary)); - if (ARY_SHARED_P(ary)) { - return ARY_SHARED(ary); - } - else if (ARY_SHARED_ROOT_P(ary)) { + if (ARY_SHARED_P(ary) || ARY_SHARED_ROOT_P(ary)) { return ary; } else if (OBJ_FROZEN(ary)) { diff --git a/test/ruby/test_array.rb b/test/ruby/test_array.rb index e8edcc2..f2d723f 100644 --- a/test/ruby/test_array.rb +++ b/test/ruby/test_array.rb @@ -1549,6 +1549,9 @@ class TestArray < Test::Unit::TestCase a.permutation {|x| b << x; a.replace(@cls[9, 8, 7, 6]) } assert_equal(@cls[9, 8, 7, 6], a) assert_equal(@cls[1, 2, 3, 4].permutation.to_a, b) + + bug3708 = '[ruby-dev:42067]' + assert_equal(b, @cls[0, 1, 2, 3, 4][1, 4].permutation.to_a, bug3708) end def test_repeated_permutation -- Kenta Murata OpenPGP FP = 1D69 ADDE 081C 9CC2 2E54 98C1 CEFE 8AFB 6081 B062 本を書きました!! 『Ruby 逆引きレシピ』 http://www.amazon.co.jp/dp/4798119881/mrkn-22 E-mail: mrkn@mrkn.jp twitter: http://twitter.com/mrkn/ blog: http://d.hatena.ne.jp/mrkn/