Nil.to_i returning zero

zero in Ruby is true, not false, in a boolean context.

What does false.to_i return? An exception. There is not a numeric
interpretation for false.

What about nil. nil is nothing. The only other object that evaluates
to false in a boolean context.

What does nil.to_i return? Zero. And I wonder why. How can nil be
interpreted as a number. It’s beyond me.

Anyone care to explain it to me?

So far I’ve found the following links about the issue:

http://groups.google.com/group/ruby-talk-google/browse_thread/thread/a475bb8a541f700e/b9f0cac6945a4210?lnk=gst&q=nil.to_i#b9f0cac6945a4210

What does nil.to_i return? Zero. And I wonder why. How can nil be
interpreted as a number. It’s beyond me.

Anyone care to explain it to me?

Dear Gerardo,

without claiming any particular authority, to me, this definition
of what nil.to_i should return doesn’t violate the principle of least
surprise so cherished by Ruby coders - if you have nil dollars money,
that’s 0 dollars – think of the balance of somebody who hasn’t
opened an account at “Ruby Deposit Bank” yet –
but if you wanted nil.to_i to raise an exception,
because the “Ruby-Using Logicians Club” might be unhappy with such
elliptic thinking, I might find that reasonable also.
Maybe one has to distinguish between 0 and 1 on the one hand and
false and true on the other, when coding Ruby, right from the start,
to avoid any confusion.

Best regards,

Axel

nil is nothing?
well, by some thinking zero is nothing as well.
nil.to_i returning zero is convenient.

If it returned nil, then you’d get exceptions and it would be
pointless to have nil respond to to_i
Sure, nil.to_i returning nil could also make sense in a way, but it
is really a matter of making decisions about design.

It’s just the way the language is.

It’s not C or C++ or another language. It’s Ruby.
Every language does things its own way.
this is one of those things.

On Mon, Oct 15, 2007 at 04:40:35AM +0900, Gerardo S. G?mez Garrido
wrote:

What does nil.to_i return? Zero. And I wonder why. How can nil be
interpreted as a number. It’s beyond me.

There’s been a few attempts to answer the question already. I’m
curious,
though:

What would you expect it to return, and why would you think that should
be the expected behavior?

Nothing immediately occurs to me as a better result of evaluating
nil.to_i than 0, within the context of the Ruby language, but if you
have
an alternative view I’m open to learning from it.

On 10/15/07, Chad P. [email protected] wrote:

Nothing immediately occurs to me as a better result of evaluating
nil.to_i than 0, within the context of the Ruby language, but if you have
an alternative view I’m open to learning from it.

nil.to_i

> NoMethodError: undefined method `to_i’ for nil:NilClass

Integer(nil)

> TypeError: can’t convert nil into Integer

This is on my wish list for Christmas among other things.

Quoth Michael F.:

On 10/15/07, Chad P. [email protected] wrote:

On Mon, Oct 15, 2007 at 04:40:35AM +0900, Gerardo S. G?mez Garrido
wrote:
Nothing immediately occurs to me as a better result of evaluating
nil.to_i than 0, within the context of the Ruby language, but if you have
an alternative view I’m open to learning from it.

nil.to_i

> NoMethodError: undefined method `to_i’ for nil:NilClass

Integer(nil)

> TypeError: can’t convert nil into Integer

This is on my wish list for Christmas among other things.

Thing is, #to_i explicitly does not throw errors – that’s what
Integer() is
for. Current (1.8.6) ruby doesn’t error on Integer(nil) either, but IMO
it
should.

Regards,

I expect to get a converted object or some Error (TypeError maybe?)
back from any to_
method. Giving me the same object back or nil
doesn’t make any sense…

As others have noted, I think the current behavior makes sense: I have
nil (whatever…money, cats, etc.) I’d think an integer representation
would be 0.

–Jeremy

On 10/14/07, Gerardo S. Gómez Garrido [email protected]
wrote:


http://www.jeremymcanally.com/

My books:
Ruby in Practice

My free Ruby e-book

My blogs:

http://www.rubyinpractice.com/

On 10/15/07, Konrad M. [email protected] wrote:

> TypeError: can’t convert nil into Integer

This is on my wish list for Christmas among other things.

Thing is, #to_i explicitly does not throw errors – that’s what Integer() is
for. Current (1.8.6) ruby doesn’t error on Integer(nil) either, but IMO it
should.
But Michael did not ask NilClass#to_i to throw an error, he did ask it
to go away :slight_smile:

Now I am completely impartial on the behavior, but if nil.to_i is
confusing for some folks it might be a good idea to put it away unless
other folks really need it.
My pragmatic question is therefore:
nil.to_i usecases anyone?

Cheers
Robert

On Oct 14, 3:40 pm, “Gerardo S. Gómez Garrido”
[email protected] wrote:

Anyone care to explain it to me?

In the strictest sense of what’s “proper” I suppose you are right, it
ought return a NoMethodError. However more often than not it seems to
be exactly what we would want to happen anyway. If it were not for
that convenience we’d have a bunch of these all over the place:

(x ? x.to_i : 0)

Following through with this, we also have to_s => “”, to_a => [] and
to_f => 0.0. And I support adding to_h => {}.

T.

On 10/15/07, Trans [email protected] wrote:

to false in a boolean context.

(x ? x.to_i : 0)

Following through with this, we also have to_s => “”, to_a => [] and
to_f => 0.0. And I support adding to_h => {}.
Hmm I really like that to_a will go away for everything than
Enumerations
I think therefore that to_h is not a good idea.

You know we have Facets for this kind of stuff, you might want to have
a look at it one day :wink:
R.

Robert D. wrote:

My pragmatic question is therefore:
nil.to_i usecases anyone?

I remember using it somewhere. I think I used it for catching user input
integer values like
unless val.to_i == 0; … ; end

The nil.to_something behaviour seems logical to me:

nil.to_i = Returns the integer which represents “nothing” = 0
nil.to_s = Returns the string which represents “nothing” = “”

On Oct 15, 6:27 am, “Robert D.” [email protected] wrote:

interpreted as a number. It’s beyond me.

But Michael did not ask NilClass#to_i to throw an error, he did ask it
to go away :slight_smile:

If it goes away you get a NoMethodError.

Now I am completely impartial on the behavior, but if nil.to_i is
confusing for some folks it might be a good idea to put it away unless
other folks really need it.
My pragmatic question is therefore:
nil.to_i usecases anyone?

def any_method(want_an_integer=nil)
@want_an_integer = want_an_integer.to_i
@want_an_integer + 1 # … whatever …
end

It is generally better to use nil for default parameters b/c it
reduces the potential for errors and increases the flexability of the
design. The same is true of using “to_i”. If you did it otherwise:

def any_method(want_an_integer=0)
@want_an_integer = want_an_integer
@want_an_integer + 1
end

Errors would occur on calling:

any_method(nil)

and

any_method(“0”)

And to compensate one would have to put the flexability into the call:

any_method((some_var || 0).to_i)

Which IMO, is much less desirable.

T.

Michael F. wrote:

nil.to_i

> NoMethodError: undefined method `to_i’ for nil:NilClass

Integer(nil)

> TypeError: can’t convert nil into Integer

This is on my wish list for Christmas among other things.

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…

mortee

On Mon, Oct 15, 2007 at 07:27:32PM +0900, Robert D. wrote:

Now I am completely impartial on the behavior, but if nil.to_i is
confusing for some folks it might be a good idea to put it away unless
other folks really need it.
My pragmatic question is therefore:
nil.to_i usecases anyone?

How about any circumstance in which one performs some kind of counting
function in code, and operates on the number of whatever is counted,
where no specific value is yet applied to the variable in question until
the first item is counted?

I suppose I find it more difficult to imagine a use case for nil.to_i
returning a no method error or throwing an exception.

On 10/15/07, Joachim G. [email protected] wrote:

The nil.to_something behaviour seems logical to me:

nil.to_i = Returns the integer which represents “nothing” = 0
nil.to_s = Returns the string which represents “nothing” = “”

Posted via http://www.ruby-forum.com/.

Hmm it might be a matter of taste what we can do with nil or not. I
just forgot to
think about something crucial.
nil is just different than anything else, nil can spring into life like
nothing,
and then when we think we have a value in our @ivar we might just get
nil.
Sometimes it is difficult to track these errors down, nil accepting
messages does
not make this easier.
I believe I want nil. to go away after all.
R.

On 10/15/07, Chad P. [email protected] wrote:

where no specific value is yet applied to the variable in question until
the first item is counted?

I suppose I find it more difficult to imagine a use case for nil.to_i
returning a no method error or throwing an exception.
unless you did not intent it to be nil, that had escaped me too.

On Oct 15, 9:47 am, “Robert D.” [email protected] wrote:

I suppose I find it more difficult to imagine a use case for nil.to_i
returning a no method error or throwing an exception.

unless you did not intent it to be nil, that had escaped me too.

That what tests are for. (Of course one could say that about anything,
but in this case I think it’s the better choice.)

And of course there’s always:

raise if x.nil?

T.

John J. wrote:

If it returned nil, then you’d get exceptions and it would be
pointless to have nil respond to to_i

You got it wrong. I’m not asking for #to_i returning nil.
NilClass#to_i shouldn’t be there in the first place.

Sure, nil.to_i returning nil could also make sense in a way,

Wrong. See above.

Jeremy McAnally wrote:

I expect to get a converted object or some Error (TypeError maybe?)
back from any to_
method. Giving me the same object back or nil
doesn’t make any sense…

You got it wrong too (am I that confusing? :).

As others have noted, I think the current behavior makes sense: I have
nil (whatever…money, cats, etc.) I’d think an integer representation
would be 0.

nil has other uses besides representing nothing: it means false in a
boolean context.

If nil
Under that logic then zero must evaluate to false, just like C and
Python does.
I don’t agree with that, of course.

Chand Perrin wrote:

What would you expect it to return, and why would you think that should
be the expected behavior?

I’d expect the same behavior as FalseClass and TrueClass: undefined
method.

Because if I want 0 would expect or send 0, not nil.to_i.
Because it doesn’t make sense to me that nil, which means false also,
can be represented as zero, when zero doesn’t mean false, but true.

Trans wrote:

If it were not for
that convenience we’d have a bunch of these all over the place:

(x ? x.to_i : 0)

Is that so common? Maybe I haven’t written that many scripts, but I
can’t
remember right now somewhere where I needed that. Ok, maybe parsing
parameters.

NilClass#to_s actually makes some sense in a context where you want to
serialize objects; “” means exactly nothing (in that context!)

Trans wrote:

@want_an_integer = want_an_integer

And to compensate one would have to put the flexability into the call:

any_method((some_var || 0).to_i)

Which IMO, is much less desirable.

Maybe it’s a matter of taste, but I validate parameters before calling
methods,
not inside methods. If you feed unexpected parameters to a method, well,
you
should get an exception. Right?

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…

Oh, c’mon …

Chad P. wrote:

How about any circumstance in which one performs some kind of counting
function in code, and operates on the number of whatever is counted,
where no specific value is yet applied to the variable in question until
the first item is counted?

I don’t think I understood you. Correct me plese, but I think you’re
talking
about an accumulator? In that case, you should start from zero, not nil.

On Tue, Oct 16, 2007 at 04:02:35AM +0900, Gerardo S. G?mez Garrido
wrote:

nil has other uses besides representing nothing: it means false in a
boolean context.

What purpose do you propose for nil if it isn’t differentiated in
behavior from false in that manner? Shouldn’t we then either replace
all
instance of false with nil or all instances of nil with false?

If nil
Under that logic then zero must evaluate to false, just like C and Python does.
I don’t agree with that, of course.

No . . . 0 would evaluate as 0 or true, while nil would evaluate as
false. Similarly, “1” evaluates as “1”, but “1”.to_i evaluates as 1.
That’s the point of a method like to_i, as far as I can tell.

Chand Perrin wrote:

What would you expect it to return, and why would you think that should
be the expected behavior?

I’d expect the same behavior as FalseClass and TrueClass: undefined method.

Thanks for clarifying that. That makes a certain amount of sense,
though
I’m not convinced it makes more sense than nil.to_i returning 0.

Because if I want 0 would expect or send 0, not nil.to_i.
Because it doesn’t make sense to me that nil, which means false also,
can be represented as zero, when zero doesn’t mean false, but true.

Trans made the point that eliminating to_i from the nil lineup of
methods
would suddenly result in a lot of ( x ? x.to_i : 0 ) being used. It
seems to me that nil.to_i is convenient, makes a certain amount of
logical sense, and doesn’t actually introduce unexpected behavior except
in pathological edge-cases. Am I missing some non-pathological,
non-edge
cases?

Chad P. wrote:

How about any circumstance in which one performs some kind of counting
function in code, and operates on the number of whatever is counted,
where no specific value is yet applied to the variable in question until
the first item is counted?

I don’t think I understood you. Correct me plese, but I think you’re talking
about an accumulator? In that case, you should start from zero, not nil.

. . .

On Oct 15, 1:02 pm, “Gerardo S. Gómez Garrido”
[email protected] wrote:

doesn’t make any sense…

You got it wrong too (am I that confusing? :).

I suspect the confusion comes from the fact that your initial post was
titled “nil.to_i returning zero”. Apparently the subject was a red
herring. We might have gotten more swiftly to discussing the merits of
your beliefs/suggestions had the subject been titled (for example)
“nil.to_i (and nil.to_s) should not exist”.

This isn’t criticism - I know well how it sometimes occurs that only
after a discussion has taken place do I realize what question or
statement I was really trying to make. The discussion is part of the
clarifying process.

So, having refocused the discussion on the question: “Should NilClass
have a #to_i method?”, let me throw in my opinion:

Various objects have methods that return an instance of a different
class. The most obvious is the #to_s method. By extension, your
argument that nil.to_i should not return 0 because 0 is a truth value
would further imply that false.to_s should not return “false” because
all strings are also truth values. Is it acceptable for an object (of
any class) to have a method that returns an object that behaves
differently under core language concepts (like boolean evaluation)? I
would say “yes”.

So, what other reasons exist for wanting to do away with nil.to_i? The
main (only other?) argument seems to be, “nil is special, and I want
to know for sure when I get a nil value. It’s so special, I should get
a NoMethodError if I try to do (just about) anything to it.”

I agree that it’s special. I’ve certainly seen that foo.id => 4 (when
foo is unexpectedly nil) can cause confusion.

However, which of the following is ‘better’?

Assume nil.to_i is not available

def foo( bar, jim )
bar = 0 if bar.nil? # explicit setting
a = bar.to_i * 2
b = jim.to_i * 2 # I want it to blow up if jim is nil
end

Assume nil.to_i is available

def foo( bar, jim )
a = bar.to_i * 2 # Magically treat nil as zero

raise "Jim can't be nil!" if jim.nil?
b = jim.to_i * 2

end

If the fitness criterion for ‘better’ in this case is ‘less lines of
code’, then it depends on which case is more prevalent. If the fitness
criterion is instead ‘safer’, then not having to_i seems to make sense
to me. If the fitness criterion is ‘more convenient’ or ‘more
expected’, then having to_i makes sense to those for whom 0 is a
reasonable integer representation of nil.

If I were to advocate removing nil.to_i, I would probably advocate
removing nil.to_s for the same reasons…and then I would really,
really hate life in the Rails world (and in other string interpolation
areas). For that reason alone I can’t personally vote for getting rid
of nil.to_i.