The Numeric#zero? method returns true if the number is 0 and false if it is not. The Numeric#nonzero? method returns nil if the number is 0 and the number itself if it is not.

Commentary most sage

Yep, because Ruby is the only language with inconsistent behaviour in it's standard library and core classes...

You do realize that in Ruby, only false and nil evaluate to 'false' in case/if statements? Thus, you can use zero? nonzero? just fine without ever caring about, or running into, this "feature".

Talk about the execution speed, the mediocre garbage collection implementation (both of which are vastly better in 1.9 of course), but a single oddity in a core class? Guess you'd better give up programming completely because this stuff is everywhere.

class Numeric def zero?; self == 0; end # 0.0 fun? def nonzero?; !zero?; end end

There's a fix. Love Ruby's ability to patch things up.

@Jason: Fair enough, although I did say "example" not "entire reason." I was just at the time annoyed about this one because I was inserting a Boolean value into a database via an interface which (sensibly enough) interpreted nil as NULL rather than false.

@Jason you are wrong IMO, zero IS NOT false - it makes more sense - since 0 it's an object !

@author of the rant: maybe you can do

from what I see in the doc, nonzero? is not supposed to return a boolean SO you should do either !!1.nonzero? or !1.zero?

@Anton you should do a better job of reading.

Jason stated nil and false return false in conditionals, NOT zero.

"false != 0" is not inconsistent, actually its very consistent as "Anton" said.

about the execution speed.. yes it's slow but ruby 1.9 is faster than perl, php, python.... do you want to bet? ;)

@sneakin theres no need to patch core classes, thats really bad in my opinion.

hmmm, if you are giving up a language because of an inconsistency, you should give up programming as well. Every programming language I have programmed till now has some.

@Mike - that's exactly what jason said. 0 is not false, but 1.zero? is, likewise 0.nonzero? returns nil so: <code> def whyargueaboutthis?(azero = 0, notazero = 1) if (notazero.zero? || a_zero.nonzero?) puts "we have a problem" else puts "what is the problem?" end end </code>

Who cares if it returns an actual boolean. So long as it returns something boolean enough for if/then, ?: or whatever.

nil and false are false-y, everything else is truth-y. So long as you don't do something stupid like if value == true ... then you'll be fine. Just write if value ... and be done with it.

There's plenty of reasons for using something other than ruby, but this one seems like very small beer.

it does seem like it should be consistent given that ?-methods generally return boolean. though I never much cared for the #zero? stuff anyway. thing==0 and thing!=0 seem perfectly good.

What is your new language of choice? (come on clojure!)

I assume you’re happy that Numeric#zero? returns the boolean answer whether the object is a zero and unhappy that Numeric#nonzero? does not mirror the behaviour, returning nil or self.

While I agree this is against the principle of least surprise, Numeric#nonzero? does work as expected in boolean contexts (as nil is falsy and Numeric objects are truthy).

I don’t like this discrepancy for idealistic reasons, but there is an argument for it – nonzero? was explicitely designed to be used in ‘spaceship’ methods to simplify their code. Consider an object with three properties with varying importance: pri, sec and ter. nonzero? allows you to write the comparator method like this:

def <=> other (pri <=> other.pri).nonzero? or (sec <=> other.sec).nonzero? or ter <=> other.ter end

Without nonzero? you’d need more verbose code.

@Shot Your assumption is correct, and your explanation makes sense, but still doesn't justify it for me. The Ruby convention is that methods ending with '?' are Boolean predicates. In most contexts, nonzero? returns something which can be implicitly interpreted as Boolean, but causes surprise and unnecessary debugging effort when used in a context where 'false' and 'nil' are not interpreted the same. So personally I value consistency in these sorts of cases.