Project

General

Profile

Feature #14546 ยป hash_delete_bang.patch

rringler (Ryan Ringler), 02/23/2018 06:47 PM

View differences:

hash.c
1185 1185
    }
1186 1186
}
1187 1187

  
1188
/*
1189
 *  call-seq:
1190
 *     hsh.delete!(key)                            -> value
1191
 *
1192
 *  Deletes the key-value pair and returns the value from <i>hsh</i> whose
1193
 *  key is equal to <i>key</i>. If the key is not found, it raises a
1194
 *  <em>KeyError</em> error.
1195
 *
1196
 *     h = { "a" => 100, "b" => 200 }
1197
 *     h.delete!("a")                              #=> 100
1198
 *     h.delete!("z")                              #=> KeyError
1199
 *
1200
 */
1201

  
1202
static VALUE
1203
rb_hash_delete_bang_m(VALUE hash, VALUE key)
1204
{
1205
    VALUE val;
1206

  
1207
    rb_hash_modify_check(hash);
1208
    val = rb_hash_delete_entry(hash, key);
1209

  
1210
    if (val != Qundef) {
1211
        return val;
1212
    }
1213
    else {
1214
        VALUE desc = rb_protect(rb_inspect, key, 0);
1215
        if (NIL_P(desc)) {
1216
            desc = rb_any_to_s(key);
1217
        }
1218
        desc = rb_str_ellipsize(desc, 65);
1219
        rb_key_err_raise(rb_sprintf("key not found: %"PRIsVALUE, desc), hash, key);
1220
    }
1221
}
1222

  
1188 1223
struct shift_var {
1189 1224
    VALUE key;
1190 1225
    VALUE val;
......
4686 4721

  
4687 4722
    rb_define_method(rb_cHash, "shift", rb_hash_shift, 0);
4688 4723
    rb_define_method(rb_cHash, "delete", rb_hash_delete_m, 1);
4724
    rb_define_method(rb_cHash, "delete!", rb_hash_delete_bang_m, 1);
4689 4725
    rb_define_method(rb_cHash, "delete_if", rb_hash_delete_if, 0);
4690 4726
    rb_define_method(rb_cHash, "keep_if", rb_hash_keep_if, 0);
4691 4727
    rb_define_method(rb_cHash, "select", rb_hash_select, 0);
test/ruby/test_hash.rb
383 383
    assert_equal('default 99', h1.delete(99) {|i| "default #{i}" })
384 384
  end
385 385

  
386
  def test_delete!
387
    h1 = @cls[ 1 => 'one', 2 => 'two', true => 'true' ]
388
    h2 = @cls[ 1 => 'one', 2 => 'two' ]
389
    h3 = @cls[ 2 => 'two' ]
390

  
391
    assert_equal('true', h1.delete!(true))
392
    assert_equal(h2, h1)
393

  
394
    assert_equal('one', h1.delete!(1))
395
    assert_equal(h3, h1)
396

  
397
    assert_equal('two', h1.delete!(2))
398
    assert_equal(@cls[], h1)
399

  
400
    assert_raise(KeyError) { h1.delete!(99) }
401
  end
402

  
386 403
  def test_delete_if
387 404
    base = @cls[ 1 => 'one', 2 => false, true => 'true', 'cat' => 99 ]
388 405
    h1   = @cls[ 1 => 'one', 2 => false, true => 'true' ]