summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNobuyoshi Nakada <nobu@ruby-lang.org>2021-12-03 23:13:27 +0900
committerNobuyoshi Nakada <nobu@ruby-lang.org>2022-06-17 01:22:24 +0900
commit278fefb96294adf9d27a78f919c714a31b65ef58 (patch)
treedba5f9b03d85d34209344b3f85203c15868e3bdf
parent51835135a0586f439f581beece13df20100123f0 (diff)
downloadruby-278fefb96294adf9d27a78f919c714a31b65ef58.tar.gz
ENV.merge! support multile arguments [Feature #18279]
-rw-r--r--hash.c25
-rw-r--r--spec/ruby/core/env/shared/update.rb9
-rw-r--r--test/ruby/test_env.rb8
3 files changed, 32 insertions, 10 deletions
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