summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-12-24 02:53:37 +0000
committerko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-12-24 02:53:37 +0000
commit9c6eaad72372576a3d351bc6044e74814718c137 (patch)
treeb39b1af99ea3ffaf4fbf14eac36dd6d06cc6aca3
parent0cd829c3393a143ff72fa56ea4040a82e2ecf1e0 (diff)
* hash.c (rb_hash_delete): return Qnil if there are no corresponding
entry. [Bug #10623] * hash.c (rb_hash_delete_entry): try delete and return Qundef if there are no corresponding entry. * internal.h: add rb_hash_delete_entry()'s declaration. * symbol.c: use rb_hash_delete_entry(). * thread.c: use rb_hash_delete_entry(). * ext/-test-/hash/delete.c: use rb_hash_delete_entry(). git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@48958 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog16
-rw-r--r--ext/-test-/hash/delete.c2
-rw-r--r--hash.c65
-rw-r--r--internal.h3
-rw-r--r--symbol.c2
-rw-r--r--thread.c4
6 files changed, 72 insertions, 20 deletions
diff --git a/ChangeLog b/ChangeLog
index 1a14d1377b..318727eac2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+Wed Dec 24 11:50:19 2014 Koichi Sasada <ko1@atdot.net>
+
+ * hash.c (rb_hash_delete): return Qnil if there are no corresponding
+ entry. [Bug #10623]
+
+ * hash.c (rb_hash_delete_entry): try delete and return Qundef if there
+ are no corresponding entry.
+
+ * internal.h: add rb_hash_delete_entry()'s declaration.
+
+ * symbol.c: use rb_hash_delete_entry().
+
+ * thread.c: use rb_hash_delete_entry().
+
+ * ext/-test-/hash/delete.c: use rb_hash_delete_entry().
+
Wed Dec 24 09:35:11 2014 NAKAMURA Usaku <usa@ruby-lang.org>
* ext/fiddle/extconf.rb: remove ffitarget.h generated by configure on
diff --git a/ext/-test-/hash/delete.c b/ext/-test-/hash/delete.c
index c0489e0ab7..1a7c373b97 100644
--- a/ext/-test-/hash/delete.c
+++ b/ext/-test-/hash/delete.c
@@ -3,7 +3,7 @@
static VALUE
hash_delete(VALUE hash, VALUE key)
{
- VALUE ret = rb_hash_delete(hash, key);
+ VALUE ret = rb_hash_delete_entry(hash, key);
return ret == Qundef ? Qnil : rb_ary_new_from_values(1, &ret);
}
diff --git a/hash.c b/hash.c
index 1b9b5a2e49..bd49a1dd92 100644
--- a/hash.c
+++ b/hash.c
@@ -969,22 +969,48 @@ rb_hash_index(VALUE hash, VALUE value)
return rb_hash_key(hash, value);
}
+/*
+ * delete a specified entry a given key.
+ * if there is the corresponding entry, return a value of the entry.
+ * if there is no corresponding entry, return Qundef.
+ */
VALUE
-rb_hash_delete(VALUE hash, VALUE key)
+rb_hash_delete_entry(VALUE hash, VALUE key)
{
st_data_t ktmp = (st_data_t)key, val;
- if (!RHASH(hash)->ntbl)
- return Qundef;
- if (RHASH_ITER_LEV(hash) > 0) {
- if (st_delete_safe(RHASH(hash)->ntbl, &ktmp, &val, (st_data_t)Qundef)) {
- FL_SET(hash, HASH_DELETED);
- return (VALUE)val;
- }
+ if (!RHASH(hash)->ntbl) {
+ return Qundef;
}
- else if (st_delete(RHASH(hash)->ntbl, &ktmp, &val))
+ else if (RHASH_ITER_LEV(hash) > 0 &&
+ (st_delete_safe(RHASH(hash)->ntbl, &ktmp, &val, (st_data_t)Qundef))) {
+ FL_SET(hash, HASH_DELETED);
return (VALUE)val;
- return Qundef;
+ }
+ else if (st_delete(RHASH(hash)->ntbl, &ktmp, &val)) {
+ return (VALUE)val;
+ }
+ else {
+ return Qundef;
+ }
+}
+
+/*
+ * delete a specified entry by a given key.
+ * if there is the corresponding entry, return a value of the entry.
+ * if there is no corresponding entry, return Qnil.
+ */
+VALUE
+rb_hash_delete(VALUE hash, VALUE key)
+{
+ VALUE deleted_value = rb_hash_delete_entry(hash, key);
+
+ if (deleted_value != Qundef) { /* likely pass */
+ return deleted_value;
+ }
+ else {
+ return Qnil;
+ }
}
/*
@@ -1011,12 +1037,19 @@ rb_hash_delete_m(VALUE hash, VALUE key)
VALUE val;
rb_hash_modify_check(hash);
- val = rb_hash_delete(hash, key);
- if (val != Qundef) return val;
- if (rb_block_given_p()) {
- return rb_yield(key);
+ val = rb_hash_delete_entry(hash, key);
+
+ if (val != Qundef) {
+ return val;
+ }
+ else {
+ if (rb_block_given_p()) {
+ return rb_yield(key);
+ }
+ else {
+ return Qnil;
+ }
}
- return Qnil;
}
struct shift_var {
@@ -1063,7 +1096,7 @@ rb_hash_shift(VALUE hash)
else {
rb_hash_foreach(hash, shift_i_safe, (VALUE)&var);
if (var.key != Qundef) {
- rb_hash_delete(hash, var.key);
+ rb_hash_delete_entry(hash, var.key);
return rb_assoc_new(var.key, var.val);
}
}
diff --git a/internal.h b/internal.h
index df93632769..10e85c77b8 100644
--- a/internal.h
+++ b/internal.h
@@ -1119,6 +1119,9 @@ int rb_bug_reporter_add(void (*func)(FILE *, void *), void *data);
VALUE rb_str_normalize_ospath(const char *ptr, long len);
#endif
+/* hash.c (export) */
+VALUE rb_hash_delete_entry(VALUE hash, VALUE key);
+
/* io.c (export) */
void rb_maygvl_fd_fix_cloexec(int fd);
diff --git a/symbol.c b/symbol.c
index a22a1d15e5..f067ebe3f9 100644
--- a/symbol.c
+++ b/symbol.c
@@ -740,7 +740,7 @@ rb_sym2id(VALUE sym)
RSYMBOL(sym)->id = id |= num;
/* make it permanent object */
set_id_entry(num >>= ID_SCOPE_SHIFT, fstr, sym);
- rb_hash_delete(global_symbols.dsymbol_fstr_hash, fstr);
+ rb_hash_delete_entry(global_symbols.dsymbol_fstr_hash, fstr);
}
}
else {
diff --git a/thread.c b/thread.c
index 25e36f25fb..9ceb441f8e 100644
--- a/thread.c
+++ b/thread.c
@@ -4806,13 +4806,13 @@ recursive_pop(VALUE list, VALUE obj, VALUE paired_obj)
return 0;
}
if (RB_TYPE_P(pair_list, T_HASH)) {
- rb_hash_delete(pair_list, paired_obj);
+ rb_hash_delete_entry(pair_list, paired_obj);
if (!RHASH_EMPTY_P(pair_list)) {
return 1; /* keep hash until is empty */
}
}
}
- rb_hash_delete(list, obj);
+ rb_hash_delete_entry(list, obj);
return 1;
}