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

···

--
Gerardo Santana

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

···

--
Der GMX SmartSurfer hilft bis zu 70% Ihrer Onlinekosten zu sparen!
Ideal für Modem und ISDN: GMX Handytarife 2024 | jetzt wechseln & sparen

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 Santana Gómez Garrido <gerardo.santana@gmail.com> wrote:

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:

O'Reilly Media - Technology and Business Training
Rails bitten by Ruby’s nil.to_f | DedaSys Journal
http://groups.google.com/group/ruby-talk-google/browse_thread/thread/a475bb8a541f700e/b9f0cac6945a4210?lnk=gst&q=nil.to_i#b9f0cac6945a4210

--
Gerardo Santana

--
http://www.jeremymcanally.com/

My books:
Ruby in Practice

My free Ruby e-book

My blogs:

http://www.rubyinpractice.com/

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 Mon, Oct 15, 2007 at 04:40:35AM +0900, Gerardo Santana 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.

--
CCD CopyWrite Chad Perrin [ http://ccd.apotheon.org ]
Patrick J. LoPresti: "Emacs has been replaced by a shell script which 1)
Generates a syslog message at level LOG_EMERG; 2) reduces the user's disk
quota by 100K; and 3) RUNS ED!!!!!!"

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 Oct 14, 3:40 pm, "Gerardo Santana Gómez Garrido" <gerardo.sant...@gmail.com> wrote:

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?

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.

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.

···

On 10/15/07, Chad Perrin <perrin@apotheon.com> wrote:

On Mon, Oct 15, 2007 at 04:40:35AM +0900, Gerardo Santana 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.

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.

···

On 10/15/07, Trans <transfire@gmail.com> wrote:

On Oct 14, 3:40 pm, "Gerardo Santana Gómez Garrido" > <gerardo.sant...@gmail.com> wrote:
> 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?

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 => {}.

--
what do I think about Ruby?
http://ruby-smalltalk.blogspot.com/

Quoth Michael Fellinger:

···

On 10/15/07, Chad Perrin <perrin@apotheon.com> wrote:
> On Mon, Oct 15, 2007 at 04:40:35AM +0900, Gerardo Santana 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.

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,
--
Konrad Meyer <konrad@tylerc.org> http://konrad.sobertillnoon.com/

Michael Fellinger 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

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 10/15/07, Konrad Meyer <konrad@tylerc.org> wrote:

Quoth Michael Fellinger:
> On 10/15/07, Chad Perrin <perrin@apotheon.com> wrote:
> > On Mon, Oct 15, 2007 at 04:40:35AM +0900, Gerardo Santana 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.
>
> 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.

--
what do I think about Ruby?
http://ruby-smalltalk.blogspot.com/

Robert Dober 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" = ""
...

···

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

> Quoth Michael Fellinger:

> > > > 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.

> > 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.

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.

···

On Oct 15, 6:27 am, "Robert Dober" <robert.do...@gmail.com> wrote:

On 10/15/07, Konrad Meyer <kon...@tylerc.org> wrote:
> > On 10/15/07, Chad Perrin <per...@apotheon.com> wrote:
> > > On Mon, Oct 15, 2007 at 04:40:35AM +0900, Gerardo Santana G?mez Garrido > > 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 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 Mon, Oct 15, 2007 at 07:27:32PM +0900, Robert Dober 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?

--
CCD CopyWrite Chad Perrin [ http://ccd.apotheon.org ]
Eat your crow early, while it's young and tender. Don't wait until it's
old and tough.

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.<anything> to go away after all.
R.

···

On 10/15/07, Joachim Glauche <jg@connection-net.de> wrote:

Robert Dober 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" = ""
...
--
Posted via http://www.ruby-forum.com/\.

--
what do I think about Ruby?
http://ruby-smalltalk.blogspot.com/

>
> 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.

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

···

On 10/15/07, Chad Perrin <perrin@apotheon.com> wrote:

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

--
CCD CopyWrite Chad Perrin [ http://ccd.apotheon.org ]
Eat your crow early, while it's young and tender. Don't wait until it's
old and tough.

--
what do I think about Ruby?
http://ruby-smalltalk.blogspot.com/

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.

···

On Oct 15, 9:47 am, "Robert Dober" <robert.do...@gmail.com> 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.

John Joyce 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:

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.

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 Perrin 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.

···

--
Gerardo Santana

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.

···

On Oct 15, 1:02 pm, "Gerardo Santana Gómez Garrido" <gerardo.sant...@gmail.com> wrote:

John Joyce 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.

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? :).

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 Perrin 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 Santana G?mez Garrido wrote:

--
CCD CopyWrite Chad Perrin [ http://ccd.apotheon.org ]
Marvin Minsky: "It's just incredible that a trillion-synapse computer could
actually spend Saturday afternoon watching a football game."