diff --git a/hash.c b/hash.c index 7568538214..1c36a22bc0 100644 --- a/hash.c +++ b/hash.c @@ -6589,10 +6589,12 @@ env_update_block_i(VALUE key, VALUE val, VALUE _) /* * call-seq: - * ENV.update(hash) -> ENV - * ENV.update(hash) { |name, env_val, hash_val| block } -> ENV - * ENV.merge!(hash) -> ENV - * ENV.merge!(hash) { |name, env_val, hash_val| block } -> ENV + * ENV.update -> ENV + * ENV.update(*hashes) -> ENV + * ENV.update(*hashes) { |name, env_val, hash_val| block } -> ENV + * ENV.merge! -> ENV + * ENV.merge!(*hashes) -> ENV + * ENV.merge!(*hashes) { |name, env_val, hash_val| block } -> ENV * * ENV.update is an alias for ENV.merge!. * @@ -6624,13 +6626,16 @@ env_update_block_i(VALUE key, VALUE val, VALUE _) * those following are ignored. */ static VALUE -env_update(VALUE env, VALUE hash) +env_update(int argc, VALUE *argv, VALUE env) { - if (env == hash) return env; - hash = to_hash(hash); rb_foreach_func *func = rb_block_given_p() ? env_update_block_i : env_update_i; - rb_hash_foreach(hash, func, 0); + for (int i = 0; i < argc; ++i) { + VALUE hash = argv[i]; + if (env == hash) continue; + hash = to_hash(hash); + rb_hash_foreach(hash, func, 0); + } return env; } @@ -7458,8 +7463,8 @@ Init_Hash(void) rb_define_singleton_method(envtbl, "freeze", env_freeze, 0); rb_define_singleton_method(envtbl, "invert", env_invert, 0); rb_define_singleton_method(envtbl, "replace", env_replace, 1); - rb_define_singleton_method(envtbl, "update", env_update, 1); - rb_define_singleton_method(envtbl, "merge!", env_update, 1); + rb_define_singleton_method(envtbl, "update", env_update, -1); + rb_define_singleton_method(envtbl, "merge!", env_update, -1); rb_define_singleton_method(envtbl, "inspect", env_inspect, 0); rb_define_singleton_method(envtbl, "rehash", env_none, 0); rb_define_singleton_method(envtbl, "to_a", env_to_a, 0); diff --git a/spec/ruby/core/env/shared/update.rb b/spec/ruby/core/env/shared/update.rb index 2746e86545..1142c503b8 100644 --- a/spec/ruby/core/env/shared/update.rb +++ b/spec/ruby/core/env/shared/update.rb @@ -15,6 +15,15 @@ describe :env_update, shared: true do ENV["bar"].should == "1" end + ruby_version_is "3.1" do + it "adds the multiple parameter hashes to ENV, returning ENV" do + ENV.send(@method, {"foo" => "0", "bar" => "1"}, {"baz" => "2"}).should equal(ENV) + ENV["foo"].should == "0" + ENV["bar"].should == "1" + ENV["baz"].should == "2" + end + end + it "returns ENV when no block given" do ENV.send(@method, {"foo" => "0", "bar" => "1"}).should equal(ENV) end diff --git a/test/ruby/test_env.rb b/test/ruby/test_env.rb index 87ccd5102b..e9eaf144a1 100644 --- a/test/ruby/test_env.rb +++ b/test/ruby/test_env.rb @@ -494,12 +494,20 @@ class TestEnv < Test::Unit::TestCase ENV["baz"] = "qux" ENV.update({"baz"=>"quux","a"=>"b"}) check(ENV.to_hash.to_a, [%w(foo bar), %w(baz quux), %w(a b)]) + ENV.update + check(ENV.to_hash.to_a, [%w(foo bar), %w(baz quux), %w(a b)]) + ENV.update({"foo"=>"zot"}, {"c"=>"d"}) + check(ENV.to_hash.to_a, [%w(foo zot), %w(baz quux), %w(a b), %w(c d)]) ENV.clear ENV["foo"] = "bar" ENV["baz"] = "qux" 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)]) + ENV.update {|k, v1, v2| k + "_" + v1 + "_" + v2 } + check(ENV.to_hash.to_a, [%w(foo bar), %w(baz baz_qux_quux), %w(a b)]) + ENV.update({"foo"=>"zot"}, {"c"=>"d"}) {|k, v1, v2| k + "_" + v1 + "_" + v2 } + check(ENV.to_hash.to_a, [%w(foo foo_bar_zot), %w(baz baz_qux_quux), %w(a b), %w(c d)]) end def test_huge_value