diff options
-rw-r--r-- | hash.c | 20 | ||||
-rw-r--r-- | test/ruby/test_hash.rb | 8 |
2 files changed, 26 insertions, 2 deletions
@@ -1404,6 +1404,7 @@ hash_foreach_ensure(VALUE hash) return 0; } +/* This does not manage iteration level */ int rb_hash_stlike_foreach(VALUE hash, st_foreach_callback_func *func, st_data_t arg) { @@ -1415,6 +1416,7 @@ rb_hash_stlike_foreach(VALUE hash, st_foreach_callback_func *func, st_data_t arg } } +/* This does not manage iteration level */ int rb_hash_stlike_foreach_with_replace(VALUE hash, st_foreach_check_callback_func *func, st_update_callback_func *replace, st_data_t arg) { @@ -3486,6 +3488,20 @@ transform_values_foreach_replace(st_data_t *key, st_data_t *value, st_data_t arg return ST_CONTINUE; } +static VALUE +transform_values_call(VALUE hash) +{ + rb_hash_stlike_foreach_with_replace(hash, transform_values_foreach_func, transform_values_foreach_replace, hash); + return hash; +} + +static void +transform_values(VALUE hash) +{ + hash_iter_lev_inc(hash); + rb_ensure(transform_values_call, hash, hash_foreach_ensure, hash); +} + /* * call-seq: * transform_values {|value| ... } -> new_hash @@ -3514,7 +3530,7 @@ rb_hash_transform_values(VALUE hash) SET_DEFAULT(result, Qnil); if (!RHASH_EMPTY_P(hash)) { - rb_hash_stlike_foreach_with_replace(result, transform_values_foreach_func, transform_values_foreach_replace, result); + transform_values(result); compact_after_delete(result); } @@ -3549,7 +3565,7 @@ rb_hash_transform_values_bang(VALUE hash) rb_hash_modify_check(hash); if (!RHASH_TABLE_EMPTY_P(hash)) { - rb_hash_stlike_foreach_with_replace(hash, transform_values_foreach_func, transform_values_foreach_replace, hash); + transform_values(hash); } return hash; diff --git a/test/ruby/test_hash.rb b/test/ruby/test_hash.rb index b6c18ea958..76af5b6183 100644 --- a/test/ruby/test_hash.rb +++ b/test/ruby/test_hash.rb @@ -1853,6 +1853,14 @@ class TestHash < Test::Unit::TestCase end end assert_equal(@cls[a: 2, b: 2, c: 3, d: 4, e: 5, f: 6, g: 7, h: 8, i: 9, j: 10], x) + + x = (1..1337).to_h {|k| [k, k]} + assert_raise_with_message(RuntimeError, /rehash during iteration/) do + x.transform_values! {|v| + x.rehash if v == 1337 + v * 2 + } + end end def hrec h, n, &b |