[Ironruby-core] Range#=== operator

John Lam (DLR) jflam at microsoft.com
Thu Nov 8 10:27:23 EST 2007

Forwarding this onto the list for Peter who's having mail problems ...

From: Peter Bacon Darwin [mailto:peterbacon at bacondarwin.com]
Sent: Thursday, November 08, 2007 2:35 AM
To: John Lam (DLR)
Subject: FW: Range#=== operator

I have noticed an interesting feature in the current snapshot.  If you test a numeric range against a non-numeric value, such as a string you get a System.ArgumentException whereas other Ruby implentations return false.

(1..5) === 'x'
System.ArgumentException: wrong number or type of arguments for `<=>'

(1..5) === 'x'

There are two interesting points here:

The first is that debugging code with lightweight code generation is really difficult; tracking down what actually causes the exception to be thrown is hidden by the DynamicSite layer.  If you break on the exception being thrown you have already lost the trace back to the original problem.  This is because the exception is not thrown directly but via binding to an invocation site.  Only by trawling through the code and putting break points all over the place was I able to ascertain that the problem is that when you apply the === operator to the Range the begin and end attributes of Range have the <=> operator applied to the argument (in this case you have something like FixNum <=> MutableString) and the current system is unable to find a suitable method to invoke. See RubyMethodGroupInfo.SetInvocationRuleInternal() and RubyMethodGroupInfo.GetMethodCandidate().  I.E. There is no implicit conversion between FixNum and MutableString.  How do you guys debug situations like this?

The second point is to do with this result itself.  Are you aiming to produce identical results to other Ruby implementations or are there other criteria for correctness.  Arguably the expression given above is invalid as there is no correct type conversion.  Equally false would seem a reasonable result; certainly it is false that 'x' is in the range of (1..5).  If false is what you want, what is the accepted way of dealing with the situation?  Do you want to fiddle with the protocols for type conversions?  I imagine not.  Is Range a specific case, in which case you would code a specific version of <=> operator for it?

Interestingly the following code returns false as expected:
1 == 'x'
The difference here is that the == operator is being used directly to test equality whereas early the <=> operator was being used to compare the values previously.

Of interest, both IronRuby and CRuby throw argument exceptions/errors for the following comparisons.
1 > 'x'
1 < 'x'

What are the correct semantics here?  What do you think should be done to deal with this discrepancy?

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://rubyforge.org/pipermail/ironruby-core/attachments/20071108/8de30a5c/attachment.html 

More information about the Ironruby-core mailing list