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:
Nobuyoshi Nakada 2026-01-15 20:32:20 +09:00
parent 6afac93c5c
commit 11edc286d8
No known key found for this signature in database
GPG Key ID: 3582D74E1FEE4465
Notes: git 2026-01-15 12:48:51 +00:00
2 changed files with 27 additions and 2 deletions

View File

@ -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

View File

@ -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))