# Is this A Good Thing or not?

by Gregory Brown

I've always liked the fact that nil evaluates to false. This is handy in conditional expressions and makes ||= possible.

However, something I didn't expect is a bit annoying:
nil.to_i gives you a 0, which evaluates to true in ruby.

So stuff like this happens:

```
irb(main):002:0> puts "hello" if nil.to_i
hello
=> nil```

At a first glance, it seems like zero might have been better replaced by nil or an exception.

Does anyone have any insight as to why nil.to_i returns zero and why that might be more useful or better than an alternative solution?

 Pawel Szymczykowski 2005-12-26 19:38:44 I don't get it - what you you expect to happen? You're asking to convert to an integer, so `nil` -> `0` seems pretty reasonable to me. Then if you want to test for a nonzero value, what's wrong with `if nil.to_i > 0` or else `unless nil.to_i.zero?`? If you ask me or Martha, it's a good thing. Gregory 2005-12-26 20:47:04 The conflicting code in question: ` number = ARGV[1].to_i || 2` I need to preserve ARGV[1] actually being 0 if it occurs, and if it's nil, I don't want it to be 0. I rewrote it as `number = ARGV[1] ? ARGV[1].to_i : 2` but there goes the DRY principle. Also, imagine a situation where nil.to_i is a divisor. I rather get a real exception than a 'divide by zero' which could have weird results. I'm curious as to where `nil.to_i` -> `0` is A Good Thing. nil is NOT zero. This is coming more from a mathematical point of view but undefined and zero are not even remotely the same thing. It's easy enough to work around, though. Pawel Szymczykowski 2005-12-27 00:01:01 I think I may have replied without fully grasping what you were posting about - sorry about that. Still, I don't think nil.to_i -> 0 is bad.. maybe mathematically, but it is pretty darned convenient more often than not I think. Especially when pulling possibly nil rows from a database I'd like to be integers. Maybe it's because I come from a Perlish background, but I've gotten to relying on that behavior to spare me from writing a rescue or two. Admittedly not a good habit I think, but brevity has its virtues too. :) How about.. `number = ( ARGV[1] || 2 ).to_i # Whole different kind of redundancy here!` You could always use '2' or :2 if 2.to_i is too weird, but I personally get a kick out of the fact that it's implemented. So yeah.. just ignore that - it's late over here. Gregory 2005-12-27 00:56:50 Hmm... I like your suggestion for `number = (ARGV[0] || 2).to_i`. This works and is reasonably clear and concise. As far as the underlying issue of `nil.to_i` -> `0`, I am sure it's useful somewhere. The database example is a good one. However, I'd be much happier seeing that be the default behavior of RubyDBI than for the language to throw a surprise at you when somehow something false becomes true. It's an easy fix on either end, but I just prefer consistency over convenience when it comes to the language itself. :) Patrice 2005-12-27 01:55:48 You talk about consistency. For me, consistency means, that when I ask Ruby to give me an integer, it gives me exactly that. Not nil nor (God forbid!) an exception. And if I ask for an integer of nil, 0 seems to be just the right answer. Gregory 2005-12-27 02:08:26 I guess it depends on how you look at it. To me, `true`, `false`, and `nil` represent state, not value. In the `true` and `false` cases, Ruby does not define `to_i` Yet, nil, which is the representation of the undefined state, gives you a definite value of 0. Handy, maybe. In some cases. Consistant? Not at all. Of course, I am not expecting to see a change to this, if i did I'd be writing an RCR for it. I'm just curious if anyone knows why the ruby core team decided to implement `nil.to_i` I suppose that the same can be said for `nil.to_f` and `nil.to_s` so maybe my mathematical mindset is overshadowing the obvious in this case. If 0 evaluated as a non-true value in ruby, I would not find an issue here. I'm glad that it doesn't, so I guess I can live with a bumpy thing like `nil.to_i` and friends. Pawel Szymczykowski 2005-12-27 02:22:06 It's a little bit beside the point, but one of the reasons I LOVE Ruby is because it's so easy to do even slightly subversive stuff like the following (if you really wanted to): ``` irb(main):002:0> nil.to_i => 0 irb(main):003:0> class NilClass irb(main):004:1> def to_i irb(main):005:2> nil irb(main):006:2> end irb(main):007:1> end => nil irb(main):008:0> nil.to_i => nil ``` Now that's one heck of a language. Gregory 2005-12-27 02:35:09 Haha! I just finished the following in IRb right before seeing your comment: ``` sandal@karookachoo:~\$ irb irb(main):001:0> class NilClass irb(main):002:1> def to_i; end; def to_s; end; def to_f; end irb(main):003:1> end => nil irb(main):004:0> @a.to_i || 2 => 2 irb(main):005:0> @a = 4 => 4 irb(main):006:0> @a.to_i || 2 => 4 ``` Brian 2005-12-27 05:42:01 >>if you really wanted to class NilClass; def to_i; end end What is the rule of thumb for popping in changes to core classes like that? Do it freely? Do it relunctantly? Should we worry upfront about the conflicts they might cause, or just deal with the conflicts when/if they ever happen? Gregory 2005-12-27 08:06:04 Rubyists are generally pretty liberal when it comes to opening up classes. It's often one of the coolest (and easiest) ways to solve a problem. However, it certainly depends on your application. If something can be done as easily without modifying a core class, it's probably a good thing to do so so as it lessons the chances of side effects. Still, with proper unit tests and a little forethought, popping open classes (even core classes) can often save time and be very elegant. Michael Granger 2005-12-27 10:40:58 I think the rule of thumb is that if you're writing something for reuse, do it reluctantly, but if you're writing something just for yourself then do it freely. akbar 2005-12-27 10:41:17 I think ruby considers everything as an object. So the only non-object value which is false is 'nil'. What nil.to_i gives is an object of integer object which means the presence of an object. nil is the only way to tell ruby that its a false object and my personal opinion is that this is good. Gregory 2005-12-27 11:28:01 nil is an object. ``` irb(main):001:0> nil.class => NilClass irb(main):002:0> nil.methods => ["&", "object_id", "singleton_methods", "equal?", "taint", "frozen?", "instance_variable_get", "kind_of?", "to_a", "respond_to?", "type", "protected_methods", "|", "eql?", "instance_variable_set", "hash", "is_a?", "to_s", "send", "class", "tainted?", "private_methods", "^", "__send__", "untaint", "id", "to_i", "inspect", "method", "instance_eval", "==", "===", "clone", "public_methods", "extend", "freeze", "display", "to_f", "__id__", "=~", "methods", "nil?", "dup", "instance_variables", "instance_of?"] ``` Also `false` is a false object which is of the class `FalseClass` Ross Karchner 2005-12-28 18:10:35 I'm more annoyed that 0 evaluates to true-- Python's behavior that 0 and empty sequences evaluate to false always seemed pretty reasonable.