Skip to content

Commit 529b1ea

Browse files
moste00eregon
authored andcommitted
Add Integer.try_convert for Ruby 3.1 support
1 parent 82f5ec3 commit 529b1ea

File tree

4 files changed

+41
-7
lines changed

4 files changed

+41
-7
lines changed

spec/ruby/core/integer/try_convert_spec.rb

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,28 @@
2828
it "sends #to_int to the argument and raises TypeError if it's not a kind of Integer" do
2929
obj = mock("to_int")
3030
obj.should_receive(:to_int).and_return(Object.new)
31-
-> { Integer.try_convert obj }.should raise_error(TypeError)
31+
-> {
32+
Integer.try_convert obj
33+
}.should raise_error(TypeError, "can't convert MockObject to Integer (MockObject#to_int gives Object)")
34+
end
35+
36+
it "responds with a different error message when it raises a TypeError, depending on the type of the non-Integer object :to_int returns" do
37+
obj = mock("to_int")
38+
obj.should_receive(:to_int).and_return("A String")
39+
-> {
40+
Integer.try_convert obj
41+
}.should raise_error(TypeError, "can't convert MockObject to Integer (MockObject#to_int gives String)")
42+
end
43+
44+
it "responds with a different error message when it raises a TypeError, depending on the type of the argument object :to_int was called on " do
45+
class DifferentMockObject
46+
def to_int
47+
Object.new
48+
end
49+
end
50+
-> {
51+
Integer.try_convert DifferentMockObject.new
52+
}.should raise_error(TypeError, "can't convert DifferentMockObject to Integer (DifferentMockObject#to_int gives Object)")
3253
end
3354

3455
it "does not rescue exceptions raised by #to_int" do

spec/tags/core/integer/try_convert_tags.txt

Lines changed: 0 additions & 6 deletions
This file was deleted.

src/main/ruby/truffleruby/core/integer.rb

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,19 @@ def zero?
332332
self == 0
333333
end
334334

335+
def self.try_convert(obj)
336+
unless obj.respond_to?(:to_int)
337+
return nil
338+
end
339+
340+
result = obj.to_int
341+
if Primitive.nil?(result) or Primitive.object_kind_of?(result, Integer)
342+
return result
343+
end
344+
345+
Truffle::Type.conversion_mismatch_into(obj, Integer, :to_int, result)
346+
end
347+
335348
def self.sqrt(n)
336349
n = Primitive.rb_to_int(n)
337350
raise Math::DomainError if n.negative?

src/main/ruby/truffleruby/core/type.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,12 @@ def self.conversion_mismatch(obj, cls, meth, res)
187187
raise TypeError, "can't convert #{oc} to #{cls} (#{oc}##{meth} gives #{Primitive.object_class(res)})"
188188
end
189189

190+
# Same as conversion mismatch, with a tiny difference in error message ("into" instead of "to")
191+
def self.conversion_mismatch_into(obj, cls, meth, res)
192+
oc = Primitive.object_class(obj)
193+
raise TypeError, "can't convert #{oc} into #{cls} (#{oc}##{meth} gives #{Primitive.object_class(res)})"
194+
end
195+
190196
def self.fits_into_int?(val)
191197
Integer === val && Primitive.integer_fits_into_int(val)
192198
end

0 commit comments

Comments
 (0)