hash.c: rb_hash_delete does not call the block

* hash.c (rb_hash_delete): now does not call the block given to
  the current method.  [ruby-core:65861] [Bug #10413]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@48114 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2014-10-23 12:42:57 +00:00
Родитель d8918fa6b5
Коммит ca7835bec6
7 изменённых файлов: 65 добавлений и 7 удалений

Просмотреть файл

@ -1,3 +1,8 @@
Thu Oct 23 21:42:54 2014 Nobuyoshi Nakada <nobu@ruby-lang.org>
* 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 <nobu@ruby-lang.org>
* vm_method.c (rb_method_entry_make): warn redefinition only for

2
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`

14
ext/-test-/hash/delete.c Normal file
Просмотреть файл

@ -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);
}

Просмотреть файл

@ -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")

11
ext/-test-/hash/init.c Normal file
Просмотреть файл

@ -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);
}

14
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);

Просмотреть файл

@ -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