[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]