mirror of
https://github.com/ruby/ruby.git
synced 2026-01-26 12:14:51 +00:00
Make Array#map and Array#select more tolerant
Only when YJIT is enabled, the redefinition of `Array#<<` affects these methods.
This commit is contained in:
parent
6afac93c5c
commit
11edc286d8
Notes:
git
2026-01-15 12:48:51 +00:00
7
array.rb
7
array.rb
@ -245,7 +245,8 @@ class Array
|
|||||||
value = nil
|
value = nil
|
||||||
result = Primitive.ary_sized_alloc
|
result = Primitive.ary_sized_alloc
|
||||||
while Primitive.cexpr!(%q{ ary_fetch_next(self, LOCAL_PTR(_i), LOCAL_PTR(value)) })
|
while Primitive.cexpr!(%q{ ary_fetch_next(self, LOCAL_PTR(_i), LOCAL_PTR(value)) })
|
||||||
result << yield(value)
|
value = yield(value)
|
||||||
|
Primitive.cexpr!(%q{ rb_ary_push(result, value) })
|
||||||
end
|
end
|
||||||
result
|
result
|
||||||
end
|
end
|
||||||
@ -270,7 +271,9 @@ class Array
|
|||||||
value = nil
|
value = nil
|
||||||
result = Primitive.ary_sized_alloc
|
result = Primitive.ary_sized_alloc
|
||||||
while Primitive.cexpr!(%q{ ary_fetch_next(self, LOCAL_PTR(_i), LOCAL_PTR(value)) })
|
while Primitive.cexpr!(%q{ ary_fetch_next(self, LOCAL_PTR(_i), LOCAL_PTR(value)) })
|
||||||
result << value if yield value
|
if yield value
|
||||||
|
Primitive.cexpr!(%q{ rb_ary_push(result, value) })
|
||||||
|
end
|
||||||
end
|
end
|
||||||
result
|
result
|
||||||
end
|
end
|
||||||
|
|||||||
@ -1336,6 +1336,28 @@ class TestArray < Test::Unit::TestCase
|
|||||||
assert_equal(@cls[@cls[1,2], nil, 'dog', 'cat'], a.prepend(@cls[1, 2]))
|
assert_equal(@cls[@cls[1,2], nil, 'dog', 'cat'], a.prepend(@cls[1, 2]))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_tolerant_to_redefinition
|
||||||
|
*code = __FILE__, __LINE__+1, "#{<<-"{#"}\n#{<<-'};'}"
|
||||||
|
{#
|
||||||
|
module M
|
||||||
|
def <<(a)
|
||||||
|
super(a * 2)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
class Array; prepend M; end
|
||||||
|
ary = [*1..10]
|
||||||
|
mapped = ary.map {|i| i}
|
||||||
|
selected = ary.select {true}
|
||||||
|
module M
|
||||||
|
remove_method :<<
|
||||||
|
end
|
||||||
|
assert_equal(ary, mapped)
|
||||||
|
assert_equal(ary, selected)
|
||||||
|
};
|
||||||
|
assert_separately(%w[--disable-yjit], *code)
|
||||||
|
assert_separately(%w[--enable-yjit], *code)
|
||||||
|
end
|
||||||
|
|
||||||
def test_push
|
def test_push
|
||||||
a = @cls[1, 2, 3]
|
a = @cls[1, 2, 3]
|
||||||
assert_equal(@cls[1, 2, 3, 4, 5], a.push(4, 5))
|
assert_equal(@cls[1, 2, 3, 4, 5], a.push(4, 5))
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user