IronRuby System.DateTime NilClass - PullRequest
       13

IronRuby System.DateTime NilClass

2 голосов
/ 11 февраля 2010

Почему сравнение с нулем так нестабильно?

Просто код.

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)
>>> 

В 9.1 этот код работает как положено.

EDIT:

Обойти:

>>> i.nil?
=> false
>>> d.nil?
=> false
>>> nil
=> nil
>>> nil.nil?
=> true
>>>

1 Ответ

1 голос
/ 28 февраля 2010

Насколько я могу судить, несоответствие связано с тем, что System.DateTime определяет свой собственный метод ==, а System.Int32 - нет. Кроме того, System.Int32 - это «специальный» класс, в котором IronRuby отображает его непосредственно на Fixnum, поэтому, когда вы вызываете System.Int32 == x, вы фактически вызываете встроенный Fixnum#== метод.

Имея это в виду, вот что происходит:

С Int32, что соответствует Fixnum

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

С Int16, который не сопоставляется ни с чем и не перегружает ==

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

С DateTime, который не отображается, но делает перегрузку ==

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

Метод System::DateTime перегружен == принимает только другие System::DateTime структуры.
Затем IronRuby пытается преобразовать nil в одну из этих структур, чтобы он мог вызвать метод, который затем завершается с ошибкой, которую вы видите.

Это кажется противоречивым? Да.
Это на самом деле противоречиво? Я бы сказал, нет. Ну, не более несовместимо, чем любой другой тип CLR, который определяет свой собственный метод ==. Для меня нет смысла просто иметь специальный чехол для System::DateTime

В общем, это не имеет значения. «Правильный» способ проверить нулевое значение в ruby ​​- это вызвать .nil?, и это хорошо работает с DateTime или любым другим классом / структурой

...