1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

array.c: reduce to_ary call

* array.c (flatten): no need to call to_ary method on elements
  beyond the given level.  [ruby-core:67637] [Bug #10748]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@49400 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2015-01-25 03:04:10 +00:00
parent 7d87d0c466
commit aa436bdca6
4 changed files with 39 additions and 1 deletions

View file

@ -1,3 +1,8 @@
Sun Jan 25 12:04:12 2015 Nobuyoshi Nakada <nobu@ruby-lang.org>
* array.c (flatten): no need to call to_ary method on elements
beyond the given level. [ruby-core:67637] [Bug #10748]
Sun Jan 25 00:42:24 2015 Nobuyoshi Nakada <nobu@ruby-lang.org> Sun Jan 25 00:42:24 2015 Nobuyoshi Nakada <nobu@ruby-lang.org>
* ext/fiddle/win32/libffi.mk.tmpl: assemble without directory prefix. * ext/fiddle/win32/libffi.mk.tmpl: assemble without directory prefix.

3
NEWS
View file

@ -22,6 +22,9 @@ with all sufficient information, see the ChangeLog file.
no longer changes the receiver array instantly every time the no longer changes the receiver array instantly every time the
block is called. [Feature #10714] block is called. [Feature #10714]
* Array#flatten and Array#flatten! no longer try to call #to_ary
method on elements beyond the given level. [Bug #10748]
* IO * IO
* IO#close doesn't raise when the IO object is closed. [Feature #10718] * IO#close doesn't raise when the IO object is closed. [Feature #10718]

View file

@ -4387,11 +4387,15 @@ flatten(VALUE ary, int level, int *modified)
while (1) { while (1) {
while (i < RARRAY_LEN(ary)) { while (i < RARRAY_LEN(ary)) {
elt = RARRAY_AREF(ary, i++); elt = RARRAY_AREF(ary, i++);
if (level >= 0 && RARRAY_LEN(stack) / 2 >= level) {
rb_ary_push(result, elt);
continue;
}
tmp = rb_check_array_type(elt); tmp = rb_check_array_type(elt);
if (RBASIC(result)->klass) { if (RBASIC(result)->klass) {
rb_raise(rb_eRuntimeError, "flatten reentered"); rb_raise(rb_eRuntimeError, "flatten reentered");
} }
if (NIL_P(tmp) || (level >= 0 && RARRAY_LEN(stack) / 2 >= level)) { if (NIL_P(tmp)) {
rb_ary_push(result, elt); rb_ary_push(result, elt);
} }
else { else {

View file

@ -790,6 +790,19 @@ class TestArray < Test::Unit::TestCase
assert_not_same(a8, a9) assert_not_same(a8, a9)
end end
def test_flatten_splat
bug10748 = '[ruby-core:67637] [Bug #10748]'
o = Object.new
o.singleton_class.class_eval do
define_method(:to_ary) do
raise bug10748
end
end
a = @cls[@cls[o]]
assert_raise_with_message(RuntimeError, bug10748) {a.flatten}
assert_nothing_raised(RuntimeError, bug10748) {a.flatten(1)}
end
def test_flatten! def test_flatten!
a1 = @cls[ 1, 2, 3] a1 = @cls[ 1, 2, 3]
a2 = @cls[ 5, 6 ] a2 = @cls[ 5, 6 ]
@ -814,6 +827,19 @@ class TestArray < Test::Unit::TestCase
assert_nil(@cls[].flatten!(0), '[ruby-core:23382]') assert_nil(@cls[].flatten!(0), '[ruby-core:23382]')
end end
def test_flatten_splat!
bug10748 = '[ruby-core:67637] [Bug #10748]'
o = Object.new
o.singleton_class.class_eval do
define_method(:to_ary) do
raise bug10748
end
end
a = @cls[@cls[o]]
assert_raise_with_message(RuntimeError, bug10748) {a.flatten!}
assert_nothing_raised(RuntimeError, bug10748) {a.flatten!(1)}
end
def test_flatten_with_callcc def test_flatten_with_callcc
need_continuation need_continuation
o = Object.new o = Object.new