[Ironruby-core] Range#=== operator

Dino Viehland dinov at exchange.microsoft.com
Thu Nov 8 11:50:40 EST 2007


Here's a couple of debugging tips:
                -X:SaveAssemblies -X:StaticMethods command line options, use these when you need to see into a DynamicMethod.  Instead of DynamicMethod's we'll create methods via Reflection.Emit and we'll save them to disk at process exit as snippets???.dll (where ??? is a number, usually 1).  You can then open the assembly w/ reflector or ildasm to see what's going on in the generated code.  This is especially useful if you have a small repro snippet like the one here as snippets will be pretty easy to dig through and find the particular piece of generated code you want.

                When debugging rules in general the best place to put a break point is either the language's RubyActionBinder.MakeRule - where you'll see all language specific binding kick in (and boy does Ruby have a lot of language specific bindings currently :)!) or you can look at ActionBinder.GetRule to see the whole process take place.  Unfortunately I don't know the ruby code base well enough to give you better hints than that (but if you want know how to debug IronPython comparisons...)

                A final useful one is -X:ExceptionDetail - this will cause the CLR exception to get printed instead of a more filtered language exception.  Also if the exception comes from a DynamicSite I'll usually try and find the exceptions message somewhere in the source code which usually is in some rule generation code.

Hopefully that's helpful on the debugging side of things - and maybe some of this you've figured out but it might be useful for other people as well.

From: ironruby-core-bounces at rubyforge.org [mailto:ironruby-core-bounces at rubyforge.org] On Behalf Of John Lam (DLR)
Sent: Thursday, November 08, 2007 7:27 AM
To: ironruby-core at rubyforge.org
Subject: [Ironruby-core] Range#=== operator

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.
E.g.

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

CRuby:
(1..5) === 'x'
gives
false

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'
gives
false
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'
and
1 < 'x'



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

Regards,
Pet
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://rubyforge.org/pipermail/ironruby-core/attachments/20071108/725bf380/attachment-0001.html 


More information about the Ironruby-core mailing list