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'开发者_如何学Pythont 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
>>>
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
精彩评论