ruby-changes:31890
From: glass <ko1@a...>
Date: Tue, 3 Dec 2013 13:55:59 +0900 (JST)
Subject: [ruby-changes:31890] glass:r43969 (trunk): * array.c (ary_add_hash): set and return values because string keys
glass 2013-12-03 13:55:51 +0900 (Tue, 03 Dec 2013) New Revision: 43969 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=43969 Log: * array.c (ary_add_hash): set and return values because string keys will be frozen. [ruby-core:58809] [Bug #9202] * array.c (rb_ary_uniq_bang): ditto. * array.c (rb_ary_or): ditto. * array.c (rb_ary_uniq): ditto. * test/ruby/test_array.rb: tests for above. The patch is from normalperson (Eric Wong). Modified files: trunk/ChangeLog trunk/array.c trunk/test/ruby/test_array.rb Index: array.c =================================================================== --- array.c (revision 43968) +++ array.c (revision 43969) @@ -3905,7 +3905,8 @@ ary_add_hash(VALUE hash, VALUE ary) https://github.com/ruby/ruby/blob/trunk/array.c#L3905 long i; for (i=0; i<RARRAY_LEN(ary); i++) { - rb_hash_aset(hash, RARRAY_AREF(ary, i), Qtrue); + VALUE elt = RARRAY_AREF(ary, i); + rb_hash_aset(hash, elt, elt); } return hash; } @@ -4056,15 +4057,15 @@ rb_ary_or(VALUE ary1, VALUE ary2) https://github.com/ruby/ruby/blob/trunk/array.c#L4057 ary2 = to_ary(ary2); hash = ary_add_hash(ary_make_hash(ary1), ary2); - ary3 = rb_hash_keys(hash); + ary3 = rb_hash_values(hash); ary_recycle_hash(hash); return ary3; } static int -push_key(st_data_t key, st_data_t val, st_data_t ary) +push_val(st_data_t key, st_data_t val, st_data_t ary) { - rb_ary_push((VALUE)ary, (VALUE)key); + rb_ary_push((VALUE)ary, (VALUE)val); return ST_CONTINUE; } @@ -4137,7 +4138,7 @@ rb_ary_uniq_bang(VALUE ary) https://github.com/ruby/ruby/blob/trunk/array.c#L4138 FL_SET_EMBED(ary); } ary_resize_capa(ary, hash_size); - st_foreach(rb_hash_tbl_raw(hash), push_key, ary); + st_foreach(rb_hash_tbl_raw(hash), push_val, ary); } ary_recycle_hash(hash); @@ -4176,7 +4177,7 @@ rb_ary_uniq(VALUE ary) https://github.com/ruby/ruby/blob/trunk/array.c#L4177 } else { hash = ary_make_hash(ary); - uniq = rb_hash_keys(hash); + uniq = rb_hash_values(hash); } RBASIC_SET_CLASS(uniq, rb_obj_class(ary)); ary_recycle_hash(hash); Index: ChangeLog =================================================================== --- ChangeLog (revision 43968) +++ ChangeLog (revision 43969) @@ -1,3 +1,18 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Tue Dec 3 13:40:42 2013 Masaki Matsushita <glass.saga@g...> + + * array.c (ary_add_hash): set and return values because string keys + will be frozen. [ruby-core:58809] [Bug #9202] + + * array.c (rb_ary_uniq_bang): ditto. + + * array.c (rb_ary_or): ditto. + + * array.c (rb_ary_uniq): ditto. + + * test/ruby/test_array.rb: tests for above. + + The patch is from normalperson (Eric Wong). + Tue Dec 3 12:20:21 2013 Aman Gupta <ruby@t...> * string.c (rb_fstring): Use st_update instead of st_lookup + Index: test/ruby/test_array.rb =================================================================== --- test/ruby/test_array.rb (revision 43968) +++ test/ruby/test_array.rb (revision 43969) @@ -1507,6 +1507,13 @@ class TestArray < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_array.rb#L1507 assert_equal(d, c) assert_equal(@cls[1, 2, 3], @cls[1, 2, 3].uniq) + + a = %w(a a) + b = a.uniq + assert_equal(%w(a a), a) + assert(a.none?(&:frozen?)) + assert_equal(%w(a), b) + assert(b.none?(&:frozen?)) end def test_uniq_with_block @@ -1527,6 +1534,13 @@ class TestArray < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_array.rb#L1534 assert_equal([1,3], a) assert_equal([1], b) assert_not_same(a, b) + + a = %w(a a) + b = a.uniq {|v| v } + assert_equal(%w(a a), a) + assert(a.none?(&:frozen?)) + assert_equal(%w(a), b) + assert(b.none?(&:frozen?)) end def test_uniq! @@ -1573,6 +1587,13 @@ class TestArray < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_array.rb#L1587 a.sort_by!{|e| e[:c]} a.uniq! {|e| e[:c]} end + + a = %w(a a) + b = a.uniq + assert_equal(%w(a a), a) + assert(a.none?(&:frozen?)) + assert_equal(%w(a), b) + assert(b.none?(&:frozen?)) end def test_uniq_bang_with_block @@ -1594,6 +1615,12 @@ class TestArray < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_array.rb#L1615 b = a.uniq! {|v| v.even? } assert_equal([1,2], a) assert_equal(nil, b) + + a = %w(a a) + b = a.uniq! {|v| v } + assert_equal(%w(a), b) + assert_same(a, b) + assert b.none?(&:frozen?) end def test_uniq_bang_with_freeze @@ -1622,6 +1649,17 @@ class TestArray < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_array.rb#L1649 assert_equal(@cls[1,2], @cls[1] | @cls[2]) assert_equal(@cls[1,2], @cls[1, 1] | @cls[2, 2]) assert_equal(@cls[1,2], @cls[1, 2] | @cls[1, 2]) + + a = %w(a b c) + b = %w(a b c d e) + c = a | b + assert_equal(c, b) + assert_not_same(c, b) + assert_equal(%w(a b c), a) + assert_equal(%w(a b c d e), b) + assert(a.none?(&:frozen?)) + assert(b.none?(&:frozen?)) + assert(c.none?(&:frozen?)) end def test_combination -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/