truffleruby
truffleruby copied to clipboard
Array#inject does not accept binary operation specified by String
The expected behavior is the same for operations specified with Symbol and String objects.
ruby 3.2.1 (2023-02-08 revision 31819e82c8) [x86_64-linux]
[2,3].inject(:*) #=> 6
[2,3].inject('*') #=> 6
truffleruby 22.3.1, like ruby 3.0.3, GraalVM CE Native [x86_64-linux]
[2,3].inject(:*) #=> 6
[2,3].inject('*')
<internal:core> core/enumerable.rb:492:in `inject': TruffleRuby doesn't have a case for the org.truffleruby.core.array.ArrayNodesFactory$InjectNodeFactory$InjectNodeGen node with values of type Array(org.truffleruby.core.array.RubyArray)[[I,2] String(org.truffleruby.core.string.RubyString) org.truffleruby.language.NotProvided org.truffleruby.language.Nil (TypeError)
from org.truffleruby.core.array.ArrayNodesFactory$InjectNodeFactory$InjectNodeGen.executeAndSpecialize(ArrayNodesFactory.java:7156)
from org.truffleruby.core.array.ArrayNodesFactory$InjectNodeFactory$InjectNodeGen.execute(ArrayNodesFactory.java:6783)
from org.truffleruby.language.control.IfElseNode.execute(IfElseNode.java:43)
from org.truffleruby.language.control.SequenceNode.execute(SequenceNode.java:37)
from org.truffleruby.language.RubyMethodRootNode.execute(RubyMethodRootNode.java:65)
Thank you for the report.
Do you know which code uses this?
I wouldn't expect this to work on CRuby, it's a probably a remnant of 1.8 which accepted a mix of String and Symbols for various methods.
Also it's quite inefficient to pass a String to inject, it will have to intern it, while a Symbol is already interned.
So I think no code should use inject(String).
Nevertheless we should fix it for compatibility, but it is low priority unless used in a gem or something.
I stumbled upon this while replacing send for inject on personal code, the tests were old and still used Strings for the binary operations.
I understand it is low priority, probably affects no gem.
I reported it because it is unexpected that it fails for Arrays, but works for Range and Hash.
(1..3).inject('*') #=> 6
{a: 2, b: 4}.inject('+') #=> [:a, 2, :b, 4]