From 04fddf35734f04fd16824a847cad499465663a5f Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Tue, 1 Oct 2019 12:29:48 +0900 Subject: ENV.delete should return the result of block on non-existing key Fixes [Bug #16173] Co-Authored-By: Burdette Lamar Co-Authored-By: Jeremy Evans --- hash.c | 13 +++++++------ spec/ruby/core/env/delete_spec.rb | 7 +++++++ test/ruby/test_env.rb | 1 + 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 -- cgit v1.2.3