Bug #16173
closedENV.delete returns nil when name does not exist and block given
Added by burdettelamar@yahoo.com (Burdette Lamar) about 6 years ago. Updated over 5 years ago.
Description
Attached diff.txt:
- ENV.delete for nonexistent name and block given:
- Test enhanced to verify return value is nil.
 - Documentation corrected to say that return value is nil, not value.
 
 
Files
        
          
          Updated by alanwu (Alan Wu) about 6 years ago
          
          
        
        
          
            Actions
          
          #1
            [ruby-core:95009]
        
      
      This gives the impression that the return value is always nil, which isn't true when the environment variable exists.
Maybe it's worth clarifying that.
        
          
          Updated by nobu (Nobuyoshi Nakada) about 6 years ago
          
          
        
        
          
            Actions
          
          #2
            [ruby-core:95012]
        
      
      Comparing with Hash#delete, it looks that the document is correct and the code is wrong.
diff --git i/hash.c w/hash.c
index 8b84a14484..7880178dc8 100644
--- i/hash.c
+++ w/hash.c
@@ -4779,7 +4779,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 i/test/ruby/test_env.rb w/test/ruby/test_env.rb
index b01c3b12ee..1a7656ea7d 100644
--- i/test/ruby/test_env.rb
+++ w/test/ruby/test_env.rb
@@ -107,6 +107,7 @@
     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
        
          
          Updated by burdettelamar@yahoo.com (Burdette Lamar) about 6 years ago
          
          
        
        
          
            Actions
          
          #3
            [ruby-core:95017]
        
      
      Thanks, @nobu (Nobuyoshi Nakada), but I'm not going to propose a change to the functionality.
        
          
          Updated by burdettelamar@yahoo.com (Burdette Lamar) about 6 years ago
          
          
        
        
          
            Actions
          
          #4
            [ruby-core:95019]
        
      
      Thanks, @alanwu (Alan Wu). I'm refreshing diff.txt with more fulsome documentation, along with enhanced testing.
        
          
          Updated by burdettelamar@yahoo.com (Burdette Lamar) about 6 years ago
          
          
        
        
          
            Actions
          
          #5
        
      
      - File deleted (
diff.txt) 
        
          
          Updated by Eregon (Benoit Daloze) about 6 years ago
          
          
        
        
          
            Actions
          
          #6
            [ruby-core:95038]
        
      
      IMHO it's better to fix behavior to be consistent with Hash#delete.
And the compatibility risk seems non existent here.
So I think we should change behavior, and not change documentation which would be inconsistent with Hash#delete.
+1 for @nobu's patch.
        
          
          Updated by burdettelamar@yahoo.com (Burdette Lamar) about 6 years ago
          
          
        
        
          
            Actions
          
          #7
            [ruby-core:95063]
        
      
      I, being a member only of The Outer Party, can't merge anything here.
I'm agnostic on whether the change should be to the documentation or to the code. My part was just to note the discrepancy.
Can someone in The Inner Party take action?
Thanks,
Burdette
        
          
          Updated by jeremyevans0 (Jeremy Evans) about 6 years ago
          
          
        
        
          
            Actions
          
          #8
            [ruby-core:95065]
        
      
      I also agree that nobu's patch should be merged.
        
          
          Updated by nobu (Nobuyoshi Nakada) about 6 years ago
          
          
        
        
          
            Actions
          
          #9
            [ruby-core:95166]
        
      
      burdettelamar@yahoo.com (Burdette Lamar) wrote:
Thanks, @alanwu (Alan Wu). I'm refreshing diff.txt with more fulsome documentation, along with enhanced testing.
Thank you for the patch.
+ * Deletes the environment variable for +name+ if it exists (ignoring the block, if given); returns +nil+:
+ *   ENV.delete('LINES') # => '300'
+ *   ENV.delete('COLUMNS') { |name| fail 'boo' } # => '120'
It should return the old value, not nil.
+ * Calls the block and returns +nil+ if the environment variable does not exist and block given:
+ *   ENV.delete('NOSUCH') { |name| } # => nil
Non-empty block and non-nil result feels better to me.
        
          
          Updated by nobu (Nobuyoshi Nakada) about 6 years ago
          
          
        
        
          
            Actions
          
          #10
            [ruby-core:95170]
        
      
      
    
        
          
          Updated by nobu (Nobuyoshi Nakada) over 5 years ago
          
          
        
        
          
            Actions
          
          #11
        
      
      - Status changed from Open to Closed
 
Applied in changeset git|04fddf35734f04fd16824a847cad499465663a5f.
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