* array.c (rb_ary_reject_bang, rb_ary_delete_if): rejected
elements should be removed. fixed [Bug #2545] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@32360 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
a943788fb7
commit
e7047b8a37
@ -1,3 +1,8 @@
|
|||||||
|
Sat Jul 2 07:17:45 2011 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
|
* array.c (rb_ary_reject_bang, rb_ary_delete_if): rejected
|
||||||
|
elements should be removed. fixed [Bug #2545]
|
||||||
|
|
||||||
Sat Jul 2 01:57:00 2011 Kenta Murata <mrkn@mrkn.jp>
|
Sat Jul 2 01:57:00 2011 Kenta Murata <mrkn@mrkn.jp>
|
||||||
|
|
||||||
* NEWS: remove a description of Kernel#respond_to? because it has
|
* NEWS: remove a description of Kernel#respond_to? because it has
|
||||||
|
69
array.c
69
array.c
@ -2563,6 +2563,48 @@ rb_ary_slice_bang(int argc, VALUE *argv, VALUE ary)
|
|||||||
return rb_ary_delete_at(ary, NUM2LONG(arg1));
|
return rb_ary_delete_at(ary, NUM2LONG(arg1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static VALUE
|
||||||
|
ary_reject(VALUE orig, VALUE result)
|
||||||
|
{
|
||||||
|
long i;
|
||||||
|
int rejected = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < RARRAY_LEN(orig); i++) {
|
||||||
|
VALUE v = RARRAY_PTR(orig)[i];
|
||||||
|
if (!RTEST(rb_yield(v))) {
|
||||||
|
rb_ary_push_1(result, v);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
rejected = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return rejected ? result : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static VALUE
|
||||||
|
ary_protecting_reject(VALUE arg)
|
||||||
|
{
|
||||||
|
VALUE *args = (VALUE *)arg;
|
||||||
|
return ary_reject(args[0], args[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static VALUE
|
||||||
|
ary_reject_bang(VALUE ary)
|
||||||
|
{
|
||||||
|
VALUE args[2];
|
||||||
|
int state = 0;
|
||||||
|
|
||||||
|
rb_ary_modify_check(ary);
|
||||||
|
args[0] = ary;
|
||||||
|
args[1] = rb_ary_new();
|
||||||
|
if (!rb_protect(ary_protecting_reject, (VALUE)args, &state)) {
|
||||||
|
return Qnil;
|
||||||
|
}
|
||||||
|
rb_ary_replace(ary, args[1]);
|
||||||
|
if (state) rb_jump_tag(state);
|
||||||
|
return ary;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* call-seq:
|
* call-seq:
|
||||||
* ary.reject! {|item| block } -> ary or nil
|
* ary.reject! {|item| block } -> ary or nil
|
||||||
@ -2580,23 +2622,8 @@ rb_ary_slice_bang(int argc, VALUE *argv, VALUE ary)
|
|||||||
static VALUE
|
static VALUE
|
||||||
rb_ary_reject_bang(VALUE ary)
|
rb_ary_reject_bang(VALUE ary)
|
||||||
{
|
{
|
||||||
long i1, i2;
|
|
||||||
|
|
||||||
RETURN_ENUMERATOR(ary, 0, 0);
|
RETURN_ENUMERATOR(ary, 0, 0);
|
||||||
rb_ary_modify(ary);
|
return ary_reject_bang(ary);
|
||||||
for (i1 = i2 = 0; i1 < RARRAY_LEN(ary); i1++) {
|
|
||||||
VALUE v = RARRAY_PTR(ary)[i1];
|
|
||||||
if (RTEST(rb_yield(v))) continue;
|
|
||||||
if (i1 != i2) {
|
|
||||||
rb_ary_store(ary, i2, v);
|
|
||||||
}
|
|
||||||
i2++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (RARRAY_LEN(ary) == i2) return Qnil;
|
|
||||||
if (i2 < RARRAY_LEN(ary))
|
|
||||||
ARY_SET_LEN(ary, i2);
|
|
||||||
return ary;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -2615,10 +2642,12 @@ rb_ary_reject_bang(VALUE ary)
|
|||||||
static VALUE
|
static VALUE
|
||||||
rb_ary_reject(VALUE ary)
|
rb_ary_reject(VALUE ary)
|
||||||
{
|
{
|
||||||
|
VALUE rejected_ary;
|
||||||
|
|
||||||
RETURN_ENUMERATOR(ary, 0, 0);
|
RETURN_ENUMERATOR(ary, 0, 0);
|
||||||
ary = rb_ary_dup(ary);
|
rejected_ary = rb_ary_new();
|
||||||
rb_ary_reject_bang(ary);
|
ary_reject(ary, rejected_ary);
|
||||||
return ary;
|
return rejected_ary;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -2640,7 +2669,7 @@ static VALUE
|
|||||||
rb_ary_delete_if(VALUE ary)
|
rb_ary_delete_if(VALUE ary)
|
||||||
{
|
{
|
||||||
RETURN_ENUMERATOR(ary, 0, 0);
|
RETURN_ENUMERATOR(ary, 0, 0);
|
||||||
rb_ary_reject_bang(ary);
|
ary_reject_bang(ary);
|
||||||
return ary;
|
return ary;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -607,6 +607,11 @@ class TestArray < Test::Unit::TestCase
|
|||||||
a = @cls[ 1, 2, 3, 4, 5 ]
|
a = @cls[ 1, 2, 3, 4, 5 ]
|
||||||
assert_equal(a, a.delete_if { |i| i > 3 })
|
assert_equal(a, a.delete_if { |i| i > 3 })
|
||||||
assert_equal(@cls[1, 2, 3], a)
|
assert_equal(@cls[1, 2, 3], a)
|
||||||
|
|
||||||
|
bug2545 = '[ruby-core:27366]'
|
||||||
|
a = @cls[ 5, 6, 7, 8, 9, 10 ]
|
||||||
|
assert_equal(9, a.delete_if {|i| break i if i > 8; i < 7})
|
||||||
|
assert_equal(@cls[7, 8], a, bug2545)
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_dup
|
def test_dup
|
||||||
@ -1087,6 +1092,11 @@ class TestArray < Test::Unit::TestCase
|
|||||||
a = @cls[ 1, 2, 3, 4, 5 ]
|
a = @cls[ 1, 2, 3, 4, 5 ]
|
||||||
assert_equal(a, a.reject! { |i| i > 3 })
|
assert_equal(a, a.reject! { |i| i > 3 })
|
||||||
assert_equal(@cls[1, 2, 3], a)
|
assert_equal(@cls[1, 2, 3], a)
|
||||||
|
|
||||||
|
bug2545 = '[ruby-core:27366]'
|
||||||
|
a = @cls[ 5, 6, 7, 8, 9, 10 ]
|
||||||
|
assert_equal(9, a.reject! {|i| break i if i > 8; i < 7})
|
||||||
|
assert_equal(@cls[7, 8], a, bug2545)
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_replace
|
def test_replace
|
||||||
|
Loading…
x
Reference in New Issue
Block a user