truffleruby icon indicating copy to clipboard operation
truffleruby copied to clipboard

Array#inject does not accept binary operation specified by String

Open Maumagnaguagno opened this issue 2 years ago • 2 comments

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)

Maumagnaguagno avatar Mar 12 '23 07:03 Maumagnaguagno

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.

eregon avatar Mar 13 '23 15:03 eregon

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]

Maumagnaguagno avatar Mar 13 '23 17:03 Maumagnaguagno