* hash.c (rb_hash_delete_key): delete the entry without calling block.
* hash.c (rb_hash_shift): should consider iter_lev too. * hash.c (delete_if_i): use rb_hash_delete_key() so that the block isn't called twice. [ruby-core:11556] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12936 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
686535d403
commit
4edc1d8c9c
@ -1,3 +1,12 @@
|
|||||||
|
Wed Aug 15 13:50:10 2007 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
|
* hash.c (rb_hash_delete_key): delete the entry without calling block.
|
||||||
|
|
||||||
|
* hash.c (rb_hash_shift): should consider iter_lev too.
|
||||||
|
|
||||||
|
* hash.c (delete_if_i): use rb_hash_delete_key() so that the block
|
||||||
|
isn't called twice. [ruby-core:11556]
|
||||||
|
|
||||||
Wed Aug 15 13:39:25 2007 Koichi Sasada <ko1@atdot.net>
|
Wed Aug 15 13:39:25 2007 Koichi Sasada <ko1@atdot.net>
|
||||||
|
|
||||||
* process.c (proc_geteuid): fix strange cast. [ruby-dev:31417]
|
* process.c (proc_geteuid): fix strange cast. [ruby-dev:31417]
|
||||||
|
53
hash.c
53
hash.c
@ -594,6 +594,22 @@ rb_hash_index(VALUE hash, VALUE value)
|
|||||||
return rb_hash_key(hash, value);
|
return rb_hash_key(hash, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static VALUE
|
||||||
|
rb_hash_delete_key(VALUE hash, VALUE key)
|
||||||
|
{
|
||||||
|
st_data_t ktmp = (st_data_t)key, val;
|
||||||
|
|
||||||
|
if (RHASH(hash)->iter_lev > 0) {
|
||||||
|
if (st_delete_safe(RHASH(hash)->tbl, &ktmp, &val, Qundef)) {
|
||||||
|
FL_SET(hash, HASH_DELETED);
|
||||||
|
return (VALUE)val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (st_delete(RHASH(hash)->tbl, &ktmp, &val))
|
||||||
|
return (VALUE)val;
|
||||||
|
return Qundef;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* call-seq:
|
* call-seq:
|
||||||
* hsh.delete(key) => value
|
* hsh.delete(key) => value
|
||||||
@ -618,14 +634,8 @@ rb_hash_delete(VALUE hash, VALUE key)
|
|||||||
VALUE val;
|
VALUE val;
|
||||||
|
|
||||||
rb_hash_modify(hash);
|
rb_hash_modify(hash);
|
||||||
if (RHASH(hash)->iter_lev > 0) {
|
val = rb_hash_delete_key(hash, key);
|
||||||
if (st_delete_safe(RHASH(hash)->tbl, (st_data_t*)&key, &val, Qundef)) {
|
if (val != Qundef) return val;
|
||||||
FL_SET(hash, HASH_DELETED);
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (st_delete(RHASH(hash)->tbl, (st_data_t*)&key, &val))
|
|
||||||
return val;
|
|
||||||
if (rb_block_given_p()) {
|
if (rb_block_given_p()) {
|
||||||
return rb_yield(key);
|
return rb_yield(key);
|
||||||
}
|
}
|
||||||
@ -633,7 +643,6 @@ rb_hash_delete(VALUE hash, VALUE key)
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct shift_var {
|
struct shift_var {
|
||||||
int stop;
|
|
||||||
VALUE key;
|
VALUE key;
|
||||||
VALUE val;
|
VALUE val;
|
||||||
};
|
};
|
||||||
@ -642,13 +651,21 @@ static int
|
|||||||
shift_i(VALUE key, VALUE value, struct shift_var *var)
|
shift_i(VALUE key, VALUE value, struct shift_var *var)
|
||||||
{
|
{
|
||||||
if (key == Qundef) return ST_CONTINUE;
|
if (key == Qundef) return ST_CONTINUE;
|
||||||
if (var->stop) return ST_STOP;
|
if (var->key != Qundef) return ST_STOP;
|
||||||
var->stop = 1;
|
|
||||||
var->key = key;
|
var->key = key;
|
||||||
var->val = value;
|
var->val = value;
|
||||||
return ST_DELETE;
|
return ST_DELETE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
shift_i_safe(VALUE key, VALUE value, struct shift_var *var)
|
||||||
|
{
|
||||||
|
if (key == Qundef) return ST_CONTINUE;
|
||||||
|
var->key = key;
|
||||||
|
var->val = value;
|
||||||
|
return ST_STOP;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* call-seq:
|
* call-seq:
|
||||||
* hsh.shift -> anArray or obj
|
* hsh.shift -> anArray or obj
|
||||||
@ -668,10 +685,14 @@ rb_hash_shift(VALUE hash)
|
|||||||
struct shift_var var;
|
struct shift_var var;
|
||||||
|
|
||||||
rb_hash_modify(hash);
|
rb_hash_modify(hash);
|
||||||
var.stop = 0;
|
var.key = Qundef;
|
||||||
rb_hash_foreach(hash, shift_i, (st_data_t)&var);
|
rb_hash_foreach(hash, RHASH(hash)->iter_lev > 0 ? shift_i_safe : shift_i,
|
||||||
|
(st_data_t)&var);
|
||||||
|
|
||||||
if (var.stop) {
|
if (var.key != Qundef) {
|
||||||
|
if (RHASH(hash)->iter_lev > 0) {
|
||||||
|
rb_hash_delete_key(hash, var.key);
|
||||||
|
}
|
||||||
return rb_assoc_new(var.key, var.val);
|
return rb_assoc_new(var.key, var.val);
|
||||||
}
|
}
|
||||||
else if (FL_TEST(hash, HASH_PROC_DEFAULT)) {
|
else if (FL_TEST(hash, HASH_PROC_DEFAULT)) {
|
||||||
@ -687,7 +708,7 @@ delete_if_i(VALUE key, VALUE value, VALUE hash)
|
|||||||
{
|
{
|
||||||
if (key == Qundef) return ST_CONTINUE;
|
if (key == Qundef) return ST_CONTINUE;
|
||||||
if (RTEST(rb_yield_values(2, key, value))) {
|
if (RTEST(rb_yield_values(2, key, value))) {
|
||||||
rb_hash_delete(hash, key);
|
rb_hash_delete_key(hash, key);
|
||||||
}
|
}
|
||||||
return ST_CONTINUE;
|
return ST_CONTINUE;
|
||||||
}
|
}
|
||||||
@ -1618,7 +1639,7 @@ rb_hash_rassoc(VALUE hash, VALUE obj)
|
|||||||
static VALUE
|
static VALUE
|
||||||
rb_hash_flatten(int argc, VALUE *argv, VALUE hash)
|
rb_hash_flatten(int argc, VALUE *argv, VALUE hash)
|
||||||
{
|
{
|
||||||
VALUE ary, lv;
|
VALUE ary;
|
||||||
|
|
||||||
ary = rb_hash_to_a(hash);
|
ary = rb_hash_to_a(hash);
|
||||||
rb_funcall2(ary, rb_intern("flatten!"), argc, argv);
|
rb_funcall2(ary, rb_intern("flatten!"), argc, argv);
|
||||||
|
@ -266,6 +266,17 @@ class TestHash < Test::Unit::TestCase
|
|||||||
h = base.dup
|
h = base.dup
|
||||||
assert_equal(h3, h.delete_if {|k,v| v })
|
assert_equal(h3, h.delete_if {|k,v| v })
|
||||||
assert_equal(h3, h)
|
assert_equal(h3, h)
|
||||||
|
|
||||||
|
h = base.dup
|
||||||
|
n = 0
|
||||||
|
h.delete_if {|*a|
|
||||||
|
n += 1
|
||||||
|
assert_equal(2, a.size)
|
||||||
|
assert_equal(base[a[0]], a[1])
|
||||||
|
h.shift
|
||||||
|
true
|
||||||
|
}
|
||||||
|
assert_equal(base.size, n)
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_dup
|
def test_dup
|
||||||
|
Loading…
x
Reference in New Issue
Block a user