aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNobuyoshi Nakada <nobu@ruby-lang.org>2019-10-01 12:29:48 +0900
committerJeremy Evans <code@jeremyevans.net>2020-06-10 12:49:27 -0700
commit04fddf35734f04fd16824a847cad499465663a5f (patch)
treee8ab4ec2aa2181f98160eb587a3b1b35c1c51e8a
parentaab2a7cfcea8e21d3902c378e355f1a8ea97c6d5 (diff)
downloadruby-04fddf35734f04fd16824a847cad499465663a5f.tar.gz
ENV.delete should return the result of block on non-existing key
Fixes [Bug #16173] Co-Authored-By: Burdette Lamar <burdettelamar@yahoo.com> Co-Authored-By: Jeremy Evans <code@jeremyevans.net>
-rw-r--r--hash.c13
-rw-r--r--spec/ruby/core/env/delete_spec.rb7
-rw-r--r--test/ruby/test_env.rb1
3 files changed, 15 insertions, 6 deletions
diff --git a/hash.c b/hash.c
index 93fe10ea35..742480d974 100644
--- a/hash.c
+++ b/hash.c
@@ -5538,8 +5538,10 @@ env_delete(VALUE name)
/*
* call-seq:
- * ENV.delete(name) -> value
- * ENV.delete(name) { |name| block } -> value
+ * ENV.delete(name) -> value
+ * ENV.delete(name) { |name| block } -> value
+ * ENV.delete(missing_name) -> nil
+ * ENV.delete(missing_name) { |name| block } -> block_value
*
* Deletes the environment variable with +name+ if it exists and returns its value:
* ENV['foo'] = '0'
@@ -5547,9 +5549,8 @@ env_delete(VALUE name)
* Returns +nil+ if the named environment variable does not exist:
* ENV.delete('foo') # => nil
* If a block given and the environment variable does not exist,
- * yields +name+ to the block and returns +nil+:
- * ENV.delete('foo') { |name| puts name } # => nil
- * foo
+ * yields +name+ to the block and returns the value of the block:
+ * ENV.delete('foo') { |name| name * 2 } # => "foofoo"
* If a block given and the environment variable exists,
* deletes the environment variable and returns its value (ignoring the block):
* ENV['foo'] = '0'
@@ -5563,7 +5564,7 @@ env_delete_m(VALUE obj, VALUE name)
VALUE val;
val = env_delete(name);
- if (NIL_P(val) && rb_block_given_p()) rb_yield(name);
+ if (NIL_P(val) && rb_block_given_p()) val = rb_yield(name);
return val;
}
diff --git a/spec/ruby/core/env/delete_spec.rb b/spec/ruby/core/env/delete_spec.rb
index f11860b21d..36a1f2624b 100644
--- a/spec/ruby/core/env/delete_spec.rb
+++ b/spec/ruby/core/env/delete_spec.rb
@@ -30,6 +30,13 @@ describe "ENV.delete" do
ScratchPad.recorded.should == "foo"
end
+ ruby_version_is "2.8" do
+ it "returns the result of given block if the named environment variable does not exist" do
+ ENV.delete("foo")
+ ENV.delete("foo") { |name| "bar" }.should == "bar"
+ end
+ end
+
it "does not evaluate the block if the environment variable exists" do
ENV["foo"] = "bar"
ENV.delete("foo") { |name| fail "Should not happen" }
diff --git a/test/ruby/test_env.rb b/test/ruby/test_env.rb
index 6d5fc88915..6a44cf17dd 100644
--- a/test/ruby/test_env.rb
+++ b/test/ruby/test_env.rb
@@ -106,6 +106,7 @@ class TestEnv < Test::Unit::TestCase
assert_invalid_env {|v| ENV.delete(v)}
assert_nil(ENV.delete("TEST"))
assert_nothing_raised { ENV.delete(PATH_ENV) }
+ assert_equal("NO TEST", ENV.delete("TEST") {|name| "NO "+name})
end
def test_getenv