Skip to content

Commit

Permalink
[GR-40333] Add Integer.try_convert for Ruby 3.1 support (#2905)
Browse files Browse the repository at this point in the history
PullRequest: truffleruby/3682
  • Loading branch information
eregon committed Mar 7, 2023
2 parents 82f5ec3 + 6876cd3 commit 01e0ce5
Show file tree
Hide file tree
Showing 10 changed files with 27 additions and 12 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ Compatibility:
* Modify `Struct#{inspect,to_s}` to match MRI when the struct is nested inside of an anonymous class or module (@st0012, @nirvdrum).
* `Fiber.current` and `Fiber#transfer` are available without `require 'fiber'` like in CRuby 3.1 (#2733, @eregon).
* Add `freeze` keyword argument to `Marshal.load` (#2733, @andrykonchin).
* Add `Integer.try_convert` (#2733, @moste00, @eregon).

Performance:

Expand Down
2 changes: 1 addition & 1 deletion spec/ruby/core/array/try_convert_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
it "sends #to_ary to the argument and raises TypeError if it's not a kind of Array" do
obj = mock("to_ary")
obj.should_receive(:to_ary).and_return(Object.new)
-> { Array.try_convert obj }.should raise_error(TypeError)
-> { Array.try_convert obj }.should raise_error(TypeError, "can't convert MockObject to Array (MockObject#to_ary gives Object)")
end

it "does not rescue exceptions raised by #to_ary" do
Expand Down
2 changes: 1 addition & 1 deletion spec/ruby/core/hash/try_convert_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
it "sends #to_hash to the argument and raises TypeError if it's not a kind of Hash" do
obj = mock("to_hash")
obj.should_receive(:to_hash).and_return(Object.new)
-> { Hash.try_convert obj }.should raise_error(TypeError)
-> { Hash.try_convert obj }.should raise_error(TypeError, "can't convert MockObject to Hash (MockObject#to_hash gives Object)")
end

it "does not rescue exceptions raised by #to_hash" do
Expand Down
12 changes: 11 additions & 1 deletion spec/ruby/core/integer/try_convert_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,17 @@
it "sends #to_int to the argument and raises TypeError if it's not a kind of Integer" do
obj = mock("to_int")
obj.should_receive(:to_int).and_return(Object.new)
-> { Integer.try_convert obj }.should raise_error(TypeError)
-> {
Integer.try_convert obj
}.should raise_error(TypeError, "can't convert MockObject to Integer (MockObject#to_int gives Object)")
end

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
obj = mock("to_int")
obj.should_receive(:to_int).and_return("A String")
-> {
Integer.try_convert obj
}.should raise_error(TypeError, "can't convert MockObject to Integer (MockObject#to_int gives String)")
end

it "does not rescue exceptions raised by #to_int" do
Expand Down
2 changes: 1 addition & 1 deletion spec/ruby/core/io/try_convert_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
it "raises a TypeError if the object does not return an IO from #to_io" do
obj = mock("io")
obj.should_receive(:to_io).and_return("io")
-> { IO.try_convert(obj) }.should raise_error(TypeError)
-> { IO.try_convert(obj) }.should raise_error(TypeError, "can't convert MockObject to IO (MockObject#to_io gives String)")
end

it "propagates an exception raised by #to_io" do
Expand Down
6 changes: 6 additions & 0 deletions spec/ruby/core/regexp/try_convert_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,10 @@
rex.should_receive(:to_regexp).and_return(/(p(a)t[e]rn)/)
Regexp.try_convert(rex).should == /(p(a)t[e]rn)/
end

it "raises a TypeError if the object does not return an Regexp from #to_regexp" do
obj = mock("regexp")
obj.should_receive(:to_regexp).and_return("string")
-> { Regexp.try_convert(obj) }.should raise_error(TypeError, "can't convert MockObject to Regexp (MockObject#to_regexp gives String)")
end
end
2 changes: 1 addition & 1 deletion spec/ruby/core/string/try_convert_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
it "sends #to_str to the argument and raises TypeError if it's not a kind of String" do
obj = mock("to_str")
obj.should_receive(:to_str).and_return(Object.new)
-> { String.try_convert obj }.should raise_error(TypeError)
-> { String.try_convert obj }.should raise_error(TypeError, "can't convert MockObject to String (MockObject#to_str gives Object)")
end

it "does not rescue exceptions raised by #to_str" do
Expand Down
6 changes: 0 additions & 6 deletions spec/tags/core/integer/try_convert_tags.txt

This file was deleted.

4 changes: 4 additions & 0 deletions src/main/ruby/truffleruby/core/integer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,10 @@ def zero?
self == 0
end

def self.try_convert(obj)
Truffle::Type.try_convert(obj, Integer, :to_int)
end

def self.sqrt(n)
n = Primitive.rb_to_int(n)
raise Math::DomainError if n.negative?
Expand Down
2 changes: 1 addition & 1 deletion src/main/ruby/truffleruby/core/type.rb
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,7 @@ def self.execute_try_convert(obj, cls, meth)
if Primitive.nil?(ret) || Primitive.object_kind_of?(ret, cls)
ret
else
raise TypeError, "Coercion error: obj.#{meth} did NOT return a #{cls} (was #{Primitive.object_class(ret)})"
conversion_mismatch(obj, cls, meth, ret)
end
end

Expand Down

0 comments on commit 01e0ce5

Please sign in to comment.