Skip to content

Commit e7047b8

Browse files
committed
* array.c (rb_ary_reject_bang, rb_ary_delete_if): rejected
elements should be removed. fixed [Bug ruby#2545] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@32360 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
1 parent a943788 commit e7047b8

File tree

3 files changed

+64
-20
lines changed

3 files changed

+64
-20
lines changed

ChangeLog

+5
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
Sat Jul 2 07:17:45 2011 Nobuyoshi Nakada <nobu@ruby-lang.org>
2+
3+
* array.c (rb_ary_reject_bang, rb_ary_delete_if): rejected
4+
elements should be removed. fixed [Bug #2545]
5+
16
Sat Jul 2 01:57:00 2011 Kenta Murata <mrkn@mrkn.jp>
27

38
* NEWS: remove a description of Kernel#respond_to? because it has

array.c

+49-20
Original file line numberDiff line numberDiff line change
@@ -2563,6 +2563,48 @@ rb_ary_slice_bang(int argc, VALUE *argv, VALUE ary)
25632563
return rb_ary_delete_at(ary, NUM2LONG(arg1));
25642564
}
25652565

2566+
static VALUE
2567+
ary_reject(VALUE orig, VALUE result)
2568+
{
2569+
long i;
2570+
int rejected = 0;
2571+
2572+
for (i = 0; i < RARRAY_LEN(orig); i++) {
2573+
VALUE v = RARRAY_PTR(orig)[i];
2574+
if (!RTEST(rb_yield(v))) {
2575+
rb_ary_push_1(result, v);
2576+
}
2577+
else {
2578+
rejected = 1;
2579+
}
2580+
}
2581+
return rejected ? result : 0;
2582+
}
2583+
2584+
static VALUE
2585+
ary_protecting_reject(VALUE arg)
2586+
{
2587+
VALUE *args = (VALUE *)arg;
2588+
return ary_reject(args[0], args[1]);
2589+
}
2590+
2591+
static VALUE
2592+
ary_reject_bang(VALUE ary)
2593+
{
2594+
VALUE args[2];
2595+
int state = 0;
2596+
2597+
rb_ary_modify_check(ary);
2598+
args[0] = ary;
2599+
args[1] = rb_ary_new();
2600+
if (!rb_protect(ary_protecting_reject, (VALUE)args, &state)) {
2601+
return Qnil;
2602+
}
2603+
rb_ary_replace(ary, args[1]);
2604+
if (state) rb_jump_tag(state);
2605+
return ary;
2606+
}
2607+
25662608
/*
25672609
* call-seq:
25682610
* ary.reject! {|item| block } -> ary or nil
@@ -2580,23 +2622,8 @@ rb_ary_slice_bang(int argc, VALUE *argv, VALUE ary)
25802622
static VALUE
25812623
rb_ary_reject_bang(VALUE ary)
25822624
{
2583-
long i1, i2;
2584-
25852625
RETURN_ENUMERATOR(ary, 0, 0);
2586-
rb_ary_modify(ary);
2587-
for (i1 = i2 = 0; i1 < RARRAY_LEN(ary); i1++) {
2588-
VALUE v = RARRAY_PTR(ary)[i1];
2589-
if (RTEST(rb_yield(v))) continue;
2590-
if (i1 != i2) {
2591-
rb_ary_store(ary, i2, v);
2592-
}
2593-
i2++;
2594-
}
2595-
2596-
if (RARRAY_LEN(ary) == i2) return Qnil;
2597-
if (i2 < RARRAY_LEN(ary))
2598-
ARY_SET_LEN(ary, i2);
2599-
return ary;
2626+
return ary_reject_bang(ary);
26002627
}
26012628

26022629
/*
@@ -2615,10 +2642,12 @@ rb_ary_reject_bang(VALUE ary)
26152642
static VALUE
26162643
rb_ary_reject(VALUE ary)
26172644
{
2645+
VALUE rejected_ary;
2646+
26182647
RETURN_ENUMERATOR(ary, 0, 0);
2619-
ary = rb_ary_dup(ary);
2620-
rb_ary_reject_bang(ary);
2621-
return ary;
2648+
rejected_ary = rb_ary_new();
2649+
ary_reject(ary, rejected_ary);
2650+
return rejected_ary;
26222651
}
26232652

26242653
/*
@@ -2640,7 +2669,7 @@ static VALUE
26402669
rb_ary_delete_if(VALUE ary)
26412670
{
26422671
RETURN_ENUMERATOR(ary, 0, 0);
2643-
rb_ary_reject_bang(ary);
2672+
ary_reject_bang(ary);
26442673
return ary;
26452674
}
26462675

test/ruby/test_array.rb

+10
Original file line numberDiff line numberDiff line change
@@ -607,6 +607,11 @@ def test_delete_if
607607
a = @cls[ 1, 2, 3, 4, 5 ]
608608
assert_equal(a, a.delete_if { |i| i > 3 })
609609
assert_equal(@cls[1, 2, 3], a)
610+
611+
bug2545 = '[ruby-core:27366]'
612+
a = @cls[ 5, 6, 7, 8, 9, 10 ]
613+
assert_equal(9, a.delete_if {|i| break i if i > 8; i < 7})
614+
assert_equal(@cls[7, 8], a, bug2545)
610615
end
611616

612617
def test_dup
@@ -1087,6 +1092,11 @@ def test_reject!
10871092
a = @cls[ 1, 2, 3, 4, 5 ]
10881093
assert_equal(a, a.reject! { |i| i > 3 })
10891094
assert_equal(@cls[1, 2, 3], a)
1095+
1096+
bug2545 = '[ruby-core:27366]'
1097+
a = @cls[ 5, 6, 7, 8, 9, 10 ]
1098+
assert_equal(9, a.reject! {|i| break i if i > 8; i < 7})
1099+
assert_equal(@cls[7, 8], a, bug2545)
10901100
end
10911101

10921102
def test_replace

0 commit comments

Comments
 (0)