Weird Ruby: Zeroing in on a Couple of Numeric Predicates
Today we’re going to discuss a couple of really simple numeric predicates - namely
Numeric#zero?
and Numeric#nonzero?
. I assume most Ruby developers are familiar with them, as
they represent a popular alternative to doing traditional checks for zero:
if foo == 0 ...
if foo.zero? ...
if foo != 0 ...
if foo.nonzero? ...
So far, so good. Nothing really weird, right? Let’s now take a closer at the two predicate methods:
0.zero?
# => true
0.nonzero?
#=> nil
1.zero?
#=> false
1.nonzero?
#=> 1
Now this looks kind of weird…
As you can see zero?
returns true
or false
and nonzero?
returns its receiver or nil
.
So much for API symmetry. There’s a long weird story behind this inconsistency, and an interesting ticket on Ruby’s bug tracker discussing options how to address it.
Most of the time you probably won’t experience any issues related to that inconsistency, but there are certainly cases where it is going to bite you.1
As far as I’m concerned nonzero?
doesn’t exist and I simply use !zero?
all the time. Negative predicates
are pretty weird in the first place and I’ve never seen much value in them.2
I’ll end this post with a small challenge for you - what are your favourite examples of API inconsistency in Ruby?
Articles in the Series
- Weird Ruby: Pure Object-Oriented Negation
- Weird Ruby: Positive and Negative Strings
- Weird Ruby: Double Negation
- Weird Ruby: Single-quoted Heredocs
- Weird Ruby: Block Comments
- Weird Ruby: Zeroing in on a Couple of Numeric Predicates
- Weird Ruby: Invoking Lambdas
- Weird Ruby: For Loops
- Weird Ruby: Array Multiplication
- Weird Ruby: Heredoc Delimiters
- Weird Ruby: Mixing Code and Data
- Weird Ruby: A Weird Way to Filter Out Elements
- Weird Ruby: Nil Conversions
- Weird Ruby: Fun with String#split
- Weird Ruby: Incrementing Strings
- Weird Ruby: The Double Aliased Enumerable Method
-
Probably the community Ruby style guide should discourage those. ↩