-
Notifications
You must be signed in to change notification settings - Fork 63
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix Float#<=> when other responds to infinite?
#679
Fix Float#<=> when other responds to infinite?
#679
Conversation
For example, these should pass: it "returns 1 when self is Infinity and other infinite? returns value that responds is neither > or < than 0" do
obj = Object.new
def obj.infinite?
val = Object.new
def val.<(other)
false
end
def val.>(other)
false
end
val
end
(infinity_value <=> obj).should == 1
end
it "returns -1 when self is -Infinity and other infinite?=1 via value that responds to > and is greater than 0" do
obj = Object.new
def obj.infinite?
val = Object.new
def val.>(other)
true
end
val
end
(-infinity_value <=> obj).should == -1
end |
We have the junk drawer that is |
Fixes `cmp` to support comparing infinity to rhs which responds to `infinite?`, and updates the spec to current upstream comparison spec.
f4f6be7
to
540b100
Compare
…-1,0,1) for use in <=> Also adds method to raise 'comparison errors' which are ArgumentErrors with a common message format and way of handling the arguments. Can be used wherever a comparison error occurs
@seven1m Do the latest changes look like they have gone in the right direction? If so I could then refactor:
|
@stevegeek I had a minute to look at this today and decided to get a better handle on it myself. I made a commit to do pretty much the minimum to get the specs passing, and it looks good to me. I don't see the need for the Thanks so much for your work on this, I really appreciate it. |
Ok sure up to you! The point of Ill see if I can get a set of specs added upstream to |
Yeah I think I see why we need the method, but we should have specs/tests driving that. Let's do it in another PR. I'm ok with us adding tests for it in the |
Ok sure! |
Fixes
cmp
to support comparing infinity to rhs which responds toinfinite?
, and updates the spec to current upstream comparison spec.A quick point for discussion:
here I use
->as_integer()
on the Value returned frominfinite?
(which should return1
,nil
, or-1
) after checking fornil
... however it is possible that an implementation of that method returns a non-integer value. If this is the case an assertion error will occur here.If we look at Ruby, it handles this by calling
rb_cmpint
which effectively converts the value into an integer of the set of valid values[-1, 0, 1]
. It does this for non-integer values by calling< 0
and> 0
on the object - https://github.com/ruby/ruby/blob/5ccb625fbbd1e774636a9fdbe0bf1c3d38e085d5/bignum.c#L2969I could implement that same behaviour here in-line, eg I see this is done in-line here for example:
natalie/src/time_object.cpp
Line 97 in 99df60f
But I guess a function such as
rb_cmpint
would be better, to be used generally where return values for use withcmp
need converting (eg in Time as linked above).However I'm not sure where that function would live in natalie, any thoughts welcome!