Ruby Nil and Zero

The protocol of to_i says that you must return an Integer and you must not raise an exception. Both of your suggestions violate at least one of those rules. So, no, those would not only not be more logical, they would be simply invalid.

Note, however, that nil does not respond to to_int. If it did respond to to_int, that would, indeed, be "illogical".


to_i means "convert me to an integer if you can".

If you want "if you're very much integer-like, give me your integer value, else give a NoMethodError", then use .to_int.

There's another question that asks about the difference between to_i and to_int, to_s versus to_str, etc. Let me know if you'd like me to find it for you.


It fits the Ruby philosophy of permissiveness (as opposed to, for example, the strictness of Python):

nil.to_i #=> 0 
"".to_i #=> 0
"123hello".to_i #=> 123
"hello".to_i #=> 0

As noted by Zabba, you can use Kernel#Integer(string) for strict conversion.


NilClass defines #to_i for the same reason it defines a #to_a that returns []. It's giving you something of the right type but an empty sort of value.

This is actually quite useful. For example:

<%= big.long.expr.nil? ? "" : big.long.expr %>

becomes:

<%= big.long.expr %>

Much nicer! (Erb is calling #to_s which, for nil, is "".) And:

if how.now.brown.cow && how.now.brown.cow[0]
  how.now.brown.cow[0]
else
  0
end

becomes:

how.now.brown.cow.to_a[0].to_i

The short conversions exist when only a representation is needed. The long conversions are the ones that the Ruby core methods call and they require something very close. Use them if you want a type check.

That is:

thing.to_int # only works when almost Integer already. NilClass throws NoMethodError

thing.to_i # this works for anything that cares to define a conversion

Tags:

Ruby