diff --git a/ChangeLog b/ChangeLog index b0af89a968..250a8c7b2b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +Thu Oct 23 21:42:54 2014 Nobuyoshi Nakada + + * hash.c (rb_hash_delete): now does not call the block given to + the current method. [ruby-core:65861] [Bug #10413] + Thu Oct 23 19:13:26 2014 Nobuyoshi Nakada * vm_method.c (rb_method_entry_make): warn redefinition only for diff --git a/NEWS b/NEWS index ee0510bdb9..158545c0a7 100644 --- a/NEWS +++ b/NEWS @@ -289,6 +289,8 @@ with all sufficient information, see the ChangeLog file. * RUBY_INTERNAL_EVENT_GC_EXIT r47528 +* rb_hash_delete() now does not call the block given to the current method. + === Build system updates * jemalloc is optionally supported via `./configure --with-jemalloc` diff --git a/ext/-test-/hash/delete.c b/ext/-test-/hash/delete.c new file mode 100644 index 0000000000..de54e3694f --- /dev/null +++ b/ext/-test-/hash/delete.c @@ -0,0 +1,14 @@ +#include "ruby.h" + +static VALUE +hash_delete(VALUE hash, VALUE key) +{ + VALUE ret = rb_hash_delete(hash, key); + return ret == Qundef ? Qfalse : Qtrue; +} + +void +Init_delete(VALUE klass) +{ + rb_define_method(klass, "delete", hash_delete, 1); +} diff --git a/ext/-test-/hash/extconf.rb b/ext/-test-/hash/extconf.rb new file mode 100644 index 0000000000..9d4ef4f935 --- /dev/null +++ b/ext/-test-/hash/extconf.rb @@ -0,0 +1,7 @@ +$INCFLAGS << " -I$(topdir) -I$(top_srcdir)" +$srcs = Dir[File.join($srcdir, "*.{#{SRC_EXT.join(%q{,})}}")] +inits = $srcs.map {|s| File.basename(s, ".*")} +inits.delete("init") +inits.map! {|s|"X(#{s})"} +$defs << "-DTEST_INIT_FUNCS(X)=\"#{inits.join(' ')}\"" +create_makefile("-test-/hash") diff --git a/ext/-test-/hash/init.c b/ext/-test-/hash/init.c new file mode 100644 index 0000000000..9f6cbde652 --- /dev/null +++ b/ext/-test-/hash/init.c @@ -0,0 +1,11 @@ +#include "ruby.h" + +#define init(n) {void Init_##n(VALUE klass); Init_##n(klass);} + +void +Init_hash(void) +{ + VALUE mBug = rb_define_module("Bug"); + VALUE klass = rb_define_class_under(mBug, "Hash", rb_cHash); + TEST_INIT_FUNCS(init); +} diff --git a/hash.c b/hash.c index a150f935b2..4933205d67 100644 --- a/hash.c +++ b/hash.c @@ -972,8 +972,8 @@ rb_hash_index(VALUE hash, VALUE value) return rb_hash_key(hash, value); } -static VALUE -rb_hash_delete_key(VALUE hash, VALUE key) +VALUE +rb_hash_delete(VALUE hash, VALUE key) { st_data_t ktmp = (st_data_t)key, val; @@ -1008,13 +1008,13 @@ rb_hash_delete_key(VALUE hash, VALUE key) * */ -VALUE -rb_hash_delete(VALUE hash, VALUE key) +static VALUE +rb_hash_delete_m(VALUE hash, VALUE key) { VALUE val; rb_hash_modify_check(hash); - val = rb_hash_delete_key(hash, key); + val = rb_hash_delete(hash, key); if (val != Qundef) return val; if (rb_block_given_p()) { return rb_yield(key); @@ -1066,7 +1066,7 @@ rb_hash_shift(VALUE hash) else { rb_hash_foreach(hash, shift_i_safe, (VALUE)&var); if (var.key != Qundef) { - rb_hash_delete_key(hash, var.key); + rb_hash_delete(hash, var.key); return rb_assoc_new(var.key, var.val); } } @@ -3881,7 +3881,7 @@ Init_Hash(void) rb_define_method(rb_cHash,"values_at", rb_hash_values_at, -1); rb_define_method(rb_cHash,"shift", rb_hash_shift, 0); - rb_define_method(rb_cHash,"delete", rb_hash_delete, 1); + rb_define_method(rb_cHash,"delete", rb_hash_delete_m, 1); rb_define_method(rb_cHash,"delete_if", rb_hash_delete_if, 0); rb_define_method(rb_cHash,"keep_if", rb_hash_keep_if, 0); rb_define_method(rb_cHash,"select", rb_hash_select, 0); diff --git a/test/-ext-/hash/test_delete.rb b/test/-ext-/hash/test_delete.rb new file mode 100644 index 0000000000..d4f2023e75 --- /dev/null +++ b/test/-ext-/hash/test_delete.rb @@ -0,0 +1,19 @@ +require 'test/unit' +require '-test-/hash' + +class TestHash < Test::Unit::TestCase + class TestDelete < Test::Unit::TestCase + def test_delete + hash = Bug::Hash.new + hash[1] = 2 + called = false + assert_equal 1, hash.size + assert_equal true, hash.delete(1) {called = true} + assert_equal false, called, "block called" + assert_equal 0, hash.size + assert_equal false, hash.delete(1) {called = true} + assert_equal false, called, "block called" + assert_equal 0, hash.size + end + end +end