ruby-changes:49924
From: mrkn <ko1@a...>
Date: Fri, 26 Jan 2018 10:33:51 +0900 (JST)
Subject: [ruby-changes:49924] mrkn:r62042 (trunk): hash.c: support key swapping in Hash#transform_keys!
mrkn 2018-01-26 10:33:45 +0900 (Fri, 26 Jan 2018) New Revision: 62042 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=62042 Log: hash.c: support key swapping in Hash#transform_keys! * hash.c (rb_hash_transform_keys_bang): support key swapping in Hash#transform_keys! [Bug #14380] [ruby-core:84951] * test/ruby/test_hash.rb (test_transform_keys_bang): add assertions for this change Modified files: trunk/hash.c trunk/test/ruby/test_hash.rb Index: hash.c =================================================================== --- hash.c (revision 62041) +++ hash.c (revision 62042) @@ -1917,6 +1917,8 @@ rb_hash_transform_keys(VALUE hash) https://github.com/ruby/ruby/blob/trunk/hash.c#L1917 return result; } +static VALUE rb_hash_flatten(int argc, VALUE *argv, VALUE hash); + /* * call-seq: * hsh.transform_keys! {|key| block } -> hsh @@ -1940,12 +1942,14 @@ rb_hash_transform_keys_bang(VALUE hash) https://github.com/ruby/ruby/blob/trunk/hash.c#L1942 RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size); rb_hash_modify_check(hash); if (RHASH(hash)->ntbl) { - long i; - VALUE keys = rb_hash_keys(hash); - for (i = 0; i < RARRAY_LEN(keys); ++i) { - VALUE key = RARRAY_AREF(keys, i), new_key = rb_yield(key); - rb_hash_aset(hash, new_key, rb_hash_delete(hash, key)); - } + long i; + VALUE pairs = rb_hash_flatten(0, NULL, hash); + rb_hash_clear(hash); + for (i = 0; i < RARRAY_LEN(pairs); i += 2) { + VALUE key = RARRAY_AREF(pairs, i), new_key = rb_yield(key), + val = RARRAY_AREF(pairs, i+1); + rb_hash_aset(hash, new_key, val); + } } return hash; } Index: test/ruby/test_hash.rb =================================================================== --- test/ruby/test_hash.rb (revision 62041) +++ test/ruby/test_hash.rb (revision 62042) @@ -1576,6 +1576,14 @@ class TestHash < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_hash.rb#L1576 x.transform_keys!.with_index {|k, i| "#{k}.#{i}" } assert_equal(%w(a!.0 b!.1 c!.2), x.keys) + + x = @cls[1 => :a, -1 => :b] + x.transform_keys! {|k| -k } + assert_equal([-1, :a, 1, :b], x.flatten) + + x = @cls[true => :a, false => :b] + x.transform_keys! {|k| !k } + assert_equal([false, :a, true, :b], x.flatten) end def test_transform_values -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/