From: "Jörg W Mittag" Date: 2007-10-16T09:50:08+09:00 Subject: Re: nil.to_i returning zero Rick DeNatale wrote: >>> mortee wrote: >>>> Well, if you'd like it so much, why not just redefine it in your own >>>> programs? Everyone else seems to expect it to return 0 instead of being >>>> hostile by throwing an exception... > In fact, I'm almost ready to go out on the limb and suggest that it > might be nice if: [NilClass implemented +, -, *, /] [...] > which would allow sequences like: > > a ||= 0 > a += 1 > > To be just > a += 1 > > As I said ALMOST ready to go out on a limb, since I haven't spent much > time pondering the consequences. This is just an example of how easy it is to do the Null Object Refactoring in Ruby. Another nice one is class NilClass; def []; nil end end which allows things like @potentially_nil[1][:foo][:bar] to return nil instead of throwing a NoMethodError. I must admit that I don't really understand the OPs position. My interpretation is as follows: (1) nil *is not* false, but, when used in a Boolean context, one can generally reasonably *interpret* nil to be somewhat similar to false, without screwing up Boolean semantics too much. (2) nil *is not* 0, but, when used in a numerical context, one can generally reasonably *interpret* nil to be somewhat similar to 0, without screwing up numerical semantics too much. To me, (1) and (2) are *exactly* the same, but for some reason the OP seems to be perfectly comfortable with (1) but violently opposed to (2), and I don't understand what the difference is. The *whole point* of having a full fledged nil object like in Ruby or Smalltalk (or Haskell), as opposed to some null pointer like in C, C++, C# or Java, is, that my program *doesn't* blow up if I'm dealing with a nil. In C, NULL is invalid. In Java, null is invalid, it isn't even an object, it doesn't really exist. When I try to evaluate null in a Boolean context in Java, I don't get false like I would in Ruby, I get a NullPointerException and my program terminates. In C, accessing a NULL pointer will generally not even gracefully terminate but simply crash the program. That is precisely what a full fledged nil object avoids, so, to me, it makes perfect sense that said object can be reasonably used in a variety of contexts, without crashing or throwing exceptions. That is not to say, that nil.to_i returning 0 is *always* right! I do believe however, that nil.to_i throwing an exception is almost always wrong and that returning 0 is generally right. If, however, I want to multiply a series of values, some of which might be nil, it would make sense to redefine nil.to_i to return 1 (because it is the neutral element of multiplication) instead of 0 and/or additionally (re)defining nil.* to return its argument. Similarly for to_s: in a report generator, it might make sense to redefine nil.to_s to return "N/A" instead of the empty string, in a HTML table generator to return " ", in a debugger to return "nil" and so on. Sometimes it might even make sense to define method_missing to always return nil and never throw a NoMethodError. Heck, in some twisted situation it might even be desirable to be able to make nil evaluate to true in a boolean context (after all, true *is* the neutral element of conjunction), althought that is unfortunately not possible in Ruby. I hope that makes some sense and explains why it might be desirable and sensible to be able to send messages to nil, convert nil to other types and use nil in different contexts without having to worry about exceptions or crashes. jwm