IronRuby System.DateTime NilClass
-
19-09-2019 - |
Pregunta
¿Por qué comparar a nula es tan inestable?
Sólo código.
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 el código funciona como se espera.
EDIT:
Solución:
>>> i.nil?
=> false
>>> d.nil?
=> false
>>> nil
=> nil
>>> nil.nil?
=> true
>>>
Solución
Por lo que yo puedo decir, la inconsistencia se debe a System.DateTime
define su propio método == y System.Int32
no lo hace.
Por otra parte, System.Int32
es una clase "especial" en que IronRuby mapas directamente a Fixnum
, por lo que cuando se llama a System.Int32 == x
, en realidad está llamando a la incorporada en el método Fixnum#==
.
Con esto en mente, aquí es lo que sucede:
Con Int32
, que se asigna a Fixnum
x = System::Int32.MinValue # => -2147483648
x.class # => Fixnum
x == nil # => Fixnum == nil
Con Int16
la que no se asigna a cualquier cosa, y no sobrecargue ==
x = System::Int16.MinValue # => -32768 (Int16)
x.class # => System::Int16
x == nil # => Object == nil
Con DateTime
la que no se asigna, pero hace sobrecarga ==
x = System::DateTime.Now # => 1/03/2010 9:00:47 a.m.
x.class # => System::DateTime
x == nil # System::DateTime == nil
El método sobrecargado System::DateTime
==
sólo acepta otras estructuras System::DateTime
.
IronRuby entonces trata de convertir nil
a una de estas estructuras para que pueda llamar al método, que a su vez produce el error que se ve.
¿Esto parece inconsistente? Sí.
¿Es realmente inconsistente? Yo diría que no. Bueno, no es más inconsistente que cualquier otro tipo CLR que define su propio método ==
. Para mí no tiene sentido tener sólo un caso especial para System::DateTime
En general, sin embargo, no importa. La forma "correcta" para comprobar si hay nulo en rubí es llamar .nil?
, y esto funciona bien con DateTime
o cualquier otra clase / struct