Following on from the discussions about the <=> operator and the Range ==operator. The situation in the MRI is not consistent. There are some cases where an exception is thrown and some where nil is returned and in those cases sometimes this is converted to false. Matz accepted this a while back (HYPERLINK "http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/165155"http://b lade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/165155) and I don?t see any change in the later releases. Here is a quick patch I knocked up that tries to map to the MRI behaviour. The FixnumOps now has an overload on Compare that can take an object on the rhs and returns an object rather than int. This allows it to return null if the value is not compatible. The Protocols.Compare now can return null if the comparison was not valid. There is a new Protocols.CheckedCompare that will return an int (as before) or throw an ArgumentException otherwise. The RangeOps.CaseEquals now checks for null from the <=> operator and returns false in that case. This had a knock on effect across a number of classes including Comparable, IListOps, ArrayOps and Enumerable, which have been changed either to explicitly cast to int (since it is guaranteed that it will be compartible) or to call CheckedCompare instead of Compare. Pete No virus found in this outgoing message. Checked by AVG Free Edition. Version: 7.5.503 / Virus Database: 269.15.29/1124 - Release Date: 11/11/2007 10:12 -------------- next part -------------- An HTML attachment was scrubbed... URL: http://rubyforge.org/pipermail/ironruby-core/attachments/20071112/3d4c6c60/attachment-0001.html -------------- next part -------------- A non-text attachment was scrubbed... Name: ComparePatch.patch Type: application/octet-stream Size: 12385 bytes Desc: not available Url : http://rubyforge.org/pipermail/ironruby-core/attachments/20071112/3d4c6c60/attachment-0001.obj
I have just realised that the overload I created in FixnumOps is nonsense, sorry: [RubyMethod("<=>")] public static object Compare(int lhs, int rhs) { return Compare(lhs, (int)rhs); } [RubyMethod("<=>")] public static object Compare(int lhs, object rhs) { if (rhs is int) { return Compare(lhs, (int)rhs); } return null; } Since there is already an overload that takes int rhs then the second overload will never get called with an int. Therefore the first three lines of the method are never needed. That leaves this method looking like: [RubyMethod("<=>")] public static object Compare(int lhs, object rhs) { return null; } This then begs the question of is there a better way to pick up default cases like this at binding time? There is also a need for other overloads such as [RubyMethod("<=>")] public static int Compare(int lhs, double rhs) { return Convert.ToDouble(lhs).CompareTo(rhs); } But again is there a more generic method of coercion for these types. The binder already attempts to do convert parameters but in this case the conversion is the reverse (in effect converting the value of self rather than rhs). Other implementations talk about a coerce framework but this is offered due to a lack of method overloading based on types in Ruby. I assume that the way the binding works actually encourages such overloads in IronRuby. Again sorry if I am being dumb. Pete No virus found in this outgoing message. Checked by AVG Free Edition. Version: 7.5.503 / Virus Database: 269.15.29/1124 - Release Date: 11/11/2007 10:12 No virus found in this outgoing message. Checked by AVG Free Edition. Version: 7.5.503 / Virus Database: 269.15.29/1124 - Release Date: 11/11/2007 10:12 -------------- next part -------------- An HTML attachment was scrubbed... URL: http://rubyforge.org/pipermail/ironruby-core/attachments/20071112/cfc9cc3d/attachment.html
Peter Bacon Darwin wrote:> Following on from the discussions about the <=> operator and the Range > === operator. The situation in the MRI is not consistent. There are > some cases where an exception is thrown and some where nil is returned > and in those cases sometimes this is converted to false. Matz accepted > this a while back > (http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/165155) and > I don?t see any change in the later releases.If you''re going through the effort of finding all cases, please also try to update either the Rubinius specs or RubySpec (www.headius.com/rubyspec) so the information is not lost (or buried in code). This goes for other discoveries...please try to capture it through one of the community-based mechanisms. - Charlie
Will do. Can anyone explain the relationship between Rubinius and RubySpec and the stuff in the test folder of IronRuby. There is clearly overlap but is one regularly updated from the other or what? Pete -----Original Message----- From: ironruby-core-bounces at rubyforge.org [mailto:ironruby-core-bounces at rubyforge.org] On Behalf Of Charles Oliver Nutter Sent: 12 November 2007 17:56 To: ironruby-core at rubyforge.org Subject: Re: [Ironruby-core] Compare Patch If you''re going through the effort of finding all cases, please also try to update either the Rubinius specs or RubySpec (www.headius.com/rubyspec) so the information is not lost (or buried in code). This goes for other discoveries...please try to capture it through one of the community-based mechanisms. - Charlie No virus found in this outgoing message. Checked by AVG Free Edition. Version: 7.5.503 / Virus Database: 269.15.29/1124 - Release Date: 11/11/2007 10:12
Peter Bacon Darwin:> Will do. Can anyone explain the relationship between Rubinius and > RubySpec > and the stuff in the test folder of IronRuby. There is clearly overlap > but > is one regularly updated from the other or what?There is a directory in the Rubinius distribution called spec. That''s where the RSpec tests live today. I did an early integration into our tests directory, but they''re mixed in with other tests which makes it hard to sync regularly with Rubinius. This week I''m going to move those tests into their own directory (\tests\specs). After that we''ll rendezvous with Rubinius specs on a regular basis. -John
For now, use overloads for method specialization on parameter type. We might do some implicit conversions (e.g. MutableString <-> CLR string) in the binder but such conversions need to be general, not specific to any operator/method. I''m also thinking about adding support for "overloading by type and protocol" (as opposed to type only). I.e. instead of this public static void Foo(object obj) { if (RubySites.RespondsTo(obj, "bar") { ... 1 ...} else if (RubySites.RespondsTo(obj, "baz") {... 2 ...} else { ... 3 ...} } one would just write (declaratively): public static void FooForBar([HasMethod("bar")]object obj) { ... 1 ... } public static void FooForBaz([HasMethod("baz")]object obj) { ... 2 ... } public static void Foo(object obj) { ... 3 ... } But it''s not a priority right now. We''ll see. Tomas From: ironruby-core-bounces at rubyforge.org [mailto:ironruby-core-bounces at rubyforge.org] On Behalf Of Peter Bacon Darwin Sent: Monday, November 12, 2007 5:55 AM To: ironruby-core at rubyforge.org Subject: Re: [Ironruby-core] Compare Patch I have just realised that the overload I created in FixnumOps is nonsense, sorry: [RubyMethod("<=>")] public static object Compare(int lhs, int rhs) { return Compare(lhs, (int)rhs); } [RubyMethod("<=>")] public static object Compare(int lhs, object rhs) { if (rhs is int) { return Compare(lhs, (int)rhs); } return null; } Since there is already an overload that takes int rhs then the second overload will never get called with an int. Therefore the first three lines of the method are never needed. That leaves this method looking like: [RubyMethod("<=>")] public static object Compare(int lhs, object rhs) { return null; } This then begs the question of is there a better way to pick up default cases like this at binding time? There is also a need for other overloads such as [RubyMethod("<=>")] public static int Compare(int lhs, double rhs) { return Convert.ToDouble(lhs).CompareTo(rhs); } But again is there a more generic method of coercion for these types. The binder already attempts to do convert parameters but in this case the conversion is the reverse (in effect converting the value of self rather than rhs). Other implementations talk about a coerce framework but this is offered due to a lack of method overloading based on types in Ruby. I assume that the way the binding works actually encourages such overloads in IronRuby. Again sorry if I am being dumb. Pete No virus found in this outgoing message. Checked by AVG Free Edition. Version: 7.5.503 / Virus Database: 269.15.29/1124 - Release Date: 11/11/2007 10:12 No virus found in this outgoing message. Checked by AVG Free Edition. Version: 7.5.503 / Virus Database: 269.15.29/1124 - Release Date: 11/11/2007 10:12 -------------- next part -------------- An HTML attachment was scrubbed... URL: http://rubyforge.org/pipermail/ironruby-core/attachments/20071112/6c945431/attachment-0001.html
That would be interesting and very duck-like. From looking at ruby doc it appears that the Numeric class implements <=> such that it either returns 0 (if both sides are equal) or nil. Pushing my method up to Numeric and implementing it properly makes more sense. Pete -----Original Message----- From: ironruby-core-bounces at rubyforge.org [mailto:ironruby-core-bounces at rubyforge.org] On Behalf Of Tomas Matousek Sent: 12 November 2007 22:46 To: ironruby-core at rubyforge.org Subject: Re: [Ironruby-core] Compare Patch For now, use overloads for method specialization on parameter type. We might do some implicit conversions (e.g. MutableString <-> CLR string) in the binder but such conversions need to be general, not specific to any operator/method. I?m also thinking about adding support for ?overloading by type and protocol? (as opposed to type only). I.e. instead of this public static void Foo(object obj) { if (RubySites.RespondsTo(obj, ?bar?) { ? 1 ?} else if (RubySites.RespondsTo(obj, ?baz?) {? 2 ?} else { ? 3 ?} } one would just write (declaratively): public static void FooForBar([HasMethod(?bar?)]object obj) { ? 1 ? } public static void FooForBaz([HasMethod(?baz?)]object obj) { ? 2 ? } public static void Foo(object obj) { ? 3 ? } But it?s not a priority right now. We?ll see. Tomas From: ironruby-core-bounces at rubyforge.org [mailto:ironruby-core-bounces at rubyforge.org] On Behalf Of Peter Bacon Darwin Sent: Monday, November 12, 2007 5:55 AM To: ironruby-core at rubyforge.org Subject: Re: [Ironruby-core] Compare Patch Since there is already an overload that takes int rhs then the second overload will never get called with an int. Therefore the first three lines of the method are never needed. That leaves this method looking like: [RubyMethod("<=>")] public static object Compare(int lhs, object rhs) { return null; } This then begs the question of is there a better way to pick up default cases like this at binding time? No virus found in this incoming message. Checked by AVG Free Edition. Version: 7.5.503 / Virus Database: 269.15.29/1124 - Release Date: 11/11/2007 10:12 No virus found in this outgoing message. Checked by AVG Free Edition. Version: 7.5.503 / Virus Database: 269.15.29/1124 - Release Date: 11/11/2007 10:12 -------------- next part -------------- An HTML attachment was scrubbed... URL: http://rubyforge.org/pipermail/ironruby-core/attachments/20071113/01a2a735/attachment.html