aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNobuyoshi Nakada <nobu@ruby-lang.org>2019-10-01 12:23:25 +0900
committerBenoit Daloze <eregontp@gmail.com>2019-11-30 18:18:20 +0100
commit5e0479f26afe1505afd9014ea96a206a88845828 (patch)
treed474b9c77755efcc28eba64fa115dd29e8423e4d
parentb94d06096b8f2a375719ce09370e004fcb277b25 (diff)
downloadruby-5e0479f26afe1505afd9014ea96a206a88845828.tar.gz
ENV.update should not call block on existing keys
[Bug #16192]
-rw-r--r--hash.c16
-rw-r--r--test/ruby/test_env.rb2
2 files changed, 14 insertions, 4 deletions
diff --git a/hash.c b/hash.c
index e11afb04cd..6b3f844095 100644
--- a/hash.c
+++ b/hash.c
@@ -5931,8 +5931,16 @@ env_replace(VALUE env, VALUE hash)
static int
env_update_i(VALUE key, VALUE val, VALUE _)
{
- if (rb_block_given_p()) {
- val = rb_yield_values(3, key, rb_f_getenv(Qnil, key), val);
+ env_aset(key, val);
+ return ST_CONTINUE;
+}
+
+static int
+env_update_block_i(VALUE key, VALUE val, VALUE _)
+{
+ VALUE oldval = rb_f_getenv(Qnil, key);
+ if (!NIL_P(oldval)) {
+ val = rb_yield_values(3, key, oldval, val);
}
env_aset(key, val);
return ST_CONTINUE;
@@ -5955,7 +5963,9 @@ env_update(VALUE env, VALUE hash)
{
if (env == hash) return env;
hash = to_hash(hash);
- rb_hash_foreach(hash, env_update_i, 0);
+ rb_foreach_func *func = rb_block_given_p() ?
+ env_update_block_i : env_update_i;
+ rb_hash_foreach(hash, func, 0);
return env;
}
diff --git a/test/ruby/test_env.rb b/test/ruby/test_env.rb
index d9301ff76c..ffce9b740c 100644
--- a/test/ruby/test_env.rb
+++ b/test/ruby/test_env.rb
@@ -445,7 +445,7 @@ class TestEnv < Test::Unit::TestCase
ENV.clear
ENV["foo"] = "bar"
ENV["baz"] = "qux"
- ENV.update({"baz"=>"quux","a"=>"b"}) {|k, v1, v2| v1 ? k + "_" + v1 + "_" + v2 : v2 }
+ ENV.update({"baz"=>"quux","a"=>"b"}) {|k, v1, v2| k + "_" + v1 + "_" + v2 }
check(ENV.to_hash.to_a, [%w(foo bar), %w(baz baz_qux_quux), %w(a b)])
end