tags:

views:

158

answers:

1

Why comparing to null is so unstable?

Just code.

IronRuby 0.9.4.0 on .NET 2.0.50727.4927
Copyright (c) Microsoft Corporation. All rights reserved.

>>> require 'System'
=> true
>>> i = System::Int32.MinValue
=> -2147483648
>>> i==nil
=> false
>>> d = System::DateTime.Now
=> 11.02.2010 14:15:02
>>> d==nil
(ir):1: can't convert NilClass into System::DateTime (TypeError)
>>> 

In 9.1 this code works as expected.

EDIT:

workaround:

>>> i.nil?
=> false
>>> d.nil?
=> false
>>> nil
=> nil
>>> nil.nil?
=> true
>>>
+1  A: 

As far as I can tell, the inconsistency is because System.DateTime defines it's own == method, and System.Int32 does not. Furthermore, System.Int32 is a "special" class in that IronRuby maps it directly to Fixnum, so when you call System.Int32 == x, you're actually calling the built in Fixnum#== method.

With that in mind, here's what happens:

With Int32, which maps to Fixnum

x = System::Int32.MinValue # => -2147483648
x.class # => Fixnum
x == nil # => Fixnum == nil

With Int16 which doesn't map to anything, and does not overload ==

x = System::Int16.MinValue # => -32768 (Int16)
x.class # => System::Int16
x == nil # => Object == nil

With DateTime which doesn't map, but does overload ==

x = System::DateTime.Now # => 1/03/2010 9:00:47 a.m.
x.class # => System::DateTime
x == nil # System::DateTime == nil

The System::DateTime overloaded == method only accepts other System::DateTime structures.
IronRuby then tries to convert nil to one of these structures so it can call the method, which then fails with the error you see.

Does this appear inconsistent? Yes.
Is it actually inconsistent? I'd argue no. Well, no more inconsistent than any other CLR type that defines it's own == method. To me it makes no sense to just have a special case for System::DateTime

In general though, it doesn't matter. The "correct" way to check for null in ruby is to call .nil?, and this works well with DateTime or any other class/struct

Orion Edwards
@Orion Edwards yes u r right it all about mapping. But it is definitely a bug, null checking should be safe in ruby. See codeplex link for comment from Jimmy. I mark your answer as right though :)
Sergey Mirvoda
I don't see any comment from Jimmy on that Codeplex link? The only comment I see is from Tomas, who basically says the same thing that I did
Orion Edwards
oh, sorry. yes, Comment from Tomas. But issue status changed to Active by Jimmy Schementi and it is planned to _change_
Sergey Mirvoda