Skip to content

Commit 01e0ce5

Browse files
committed
[GR-40333] Add Integer.try_convert for Ruby 3.1 support (#2905)
PullRequest: truffleruby/3682
2 parents 82f5ec3 + 6876cd3 commit 01e0ce5

File tree

10 files changed

+27
-12
lines changed

10 files changed

+27
-12
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ Compatibility:
8383
* Modify `Struct#{inspect,to_s}` to match MRI when the struct is nested inside of an anonymous class or module (@st0012, @nirvdrum).
8484
* `Fiber.current` and `Fiber#transfer` are available without `require 'fiber'` like in CRuby 3.1 (#2733, @eregon).
8585
* Add `freeze` keyword argument to `Marshal.load` (#2733, @andrykonchin).
86+
* Add `Integer.try_convert` (#2733, @moste00, @eregon).
8687

8788
Performance:
8889

spec/ruby/core/array/try_convert_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
it "sends #to_ary to the argument and raises TypeError if it's not a kind of Array" do
4040
obj = mock("to_ary")
4141
obj.should_receive(:to_ary).and_return(Object.new)
42-
-> { Array.try_convert obj }.should raise_error(TypeError)
42+
-> { Array.try_convert obj }.should raise_error(TypeError, "can't convert MockObject to Array (MockObject#to_ary gives Object)")
4343
end
4444

4545
it "does not rescue exceptions raised by #to_ary" do

spec/ruby/core/hash/try_convert_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
it "sends #to_hash to the argument and raises TypeError if it's not a kind of Hash" do
4040
obj = mock("to_hash")
4141
obj.should_receive(:to_hash).and_return(Object.new)
42-
-> { Hash.try_convert obj }.should raise_error(TypeError)
42+
-> { Hash.try_convert obj }.should raise_error(TypeError, "can't convert MockObject to Hash (MockObject#to_hash gives Object)")
4343
end
4444

4545
it "does not rescue exceptions raised by #to_hash" do

spec/ruby/core/integer/try_convert_spec.rb

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,17 @@
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)")
3242
end
3343

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

spec/ruby/core/io/try_convert_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
it "raises a TypeError if the object does not return an IO from #to_io" do
3939
obj = mock("io")
4040
obj.should_receive(:to_io).and_return("io")
41-
-> { IO.try_convert(obj) }.should raise_error(TypeError)
41+
-> { IO.try_convert(obj) }.should raise_error(TypeError, "can't convert MockObject to IO (MockObject#to_io gives String)")
4242
end
4343

4444
it "propagates an exception raised by #to_io" do

spec/ruby/core/regexp/try_convert_spec.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,10 @@
1818
rex.should_receive(:to_regexp).and_return(/(p(a)t[e]rn)/)
1919
Regexp.try_convert(rex).should == /(p(a)t[e]rn)/
2020
end
21+
22+
it "raises a TypeError if the object does not return an Regexp from #to_regexp" do
23+
obj = mock("regexp")
24+
obj.should_receive(:to_regexp).and_return("string")
25+
-> { Regexp.try_convert(obj) }.should raise_error(TypeError, "can't convert MockObject to Regexp (MockObject#to_regexp gives String)")
26+
end
2127
end

spec/ruby/core/string/try_convert_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
it "sends #to_str to the argument and raises TypeError if it's not a kind of String" do
4040
obj = mock("to_str")
4141
obj.should_receive(:to_str).and_return(Object.new)
42-
-> { String.try_convert obj }.should raise_error(TypeError)
42+
-> { String.try_convert obj }.should raise_error(TypeError, "can't convert MockObject to String (MockObject#to_str gives Object)")
4343
end
4444

4545
it "does not rescue exceptions raised by #to_str" 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: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,10 @@ def zero?
332332
self == 0
333333
end
334334

335+
def self.try_convert(obj)
336+
Truffle::Type.try_convert(obj, Integer, :to_int)
337+
end
338+
335339
def self.sqrt(n)
336340
n = Primitive.rb_to_int(n)
337341
raise Math::DomainError if n.negative?

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,7 @@ def self.execute_try_convert(obj, cls, meth)
367367
if Primitive.nil?(ret) || Primitive.object_kind_of?(ret, cls)
368368
ret
369369
else
370-
raise TypeError, "Coercion error: obj.#{meth} did NOT return a #{cls} (was #{Primitive.object_class(ret)})"
370+
conversion_mismatch(obj, cls, meth, ret)
371371
end
372372
end
373373

0 commit comments

Comments
 (0)