Feature #11918


Make #finite? consistent with #nonzero?

Added by avit (Andrew Vit) over 5 years ago. Updated over 5 years ago.

Target version:


Calling .nonzero? on a number returns itself (truthy) or nil, but calling .finite? on a float is just true or false.

Floats can produce Infinity without errors and cause downstream errors if that result is unexpected. This would be nice to have:

top, bottom = 9.9, 0.0
(top / bottom).finite? or raise DivisionByZero
(top / bottom).finite? || 0.0

(9.9 / 2.0).finite? #=> 0.5
(9.9 / 0.0).finite? #=> nil

These semantics would let the user handle the desired behaviour immediately in place.

Updated by matz (Yukihiro Matsumoto) over 5 years ago

  • Status changed from Open to Feedback

Forget about consistency with nonzero?, it has sorting use-cases.
And tell me your use-case for finite? that returns nil.
Your example seems artificial for me.


Updated by avit (Andrew Vit) over 5 years ago

Hello Matz,

With zero division on Integers we expect to do one of these:

99 / 0           # default behaviour: raise ZeroDivisionError from __LINE__
99 / 0 rescue 0  # handle it here: just return 0

For Floats there is no built-in way to handle or raise it inline like that.
Infinity is not valid for common use cases, so a way to handle it would be helpful.

This is one possible technique with current ruby:

(y = 99.9 / 0).finite? ? y : (raise ZeroDivisionError)  
(y = 99.9 / 0).finite? ? y : 0.0

Yes, I understand the use case for (a <=> b).nonzero? is special.
There is also infinite? that returns (-1, nil, +1) but I don't know how that is used.
Changing finite? might not be the right way to achieve this: I leave it up to you.

Sorry if the examples look artificial: I was trying to keep it simple.
In my use case the input numbers are from other method calls, not locals/literals.


Also available in: Atom PDF