Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In ruby, is truthiness idiomatic for a method name ending with a question mark?

Is it normal for methods with a question mark to return something that's truthy (for example, a number) to indicate that something is true, or should true itself be returned?

Are there any examples of truthiness being used in the Ruby standard library or by Rails, for example?

Background: Someone wrote a String#int? method in an answer to a separate question, which returned an integer to represent true, and nil to represent false. Another user was surprised at not returning a boolean.

like image 581
Andrew Grimm Avatar asked Nov 27 '10 01:11

Andrew Grimm


4 Answers

Adding a ? to a method name in Ruby is idiomatic that the method will return true or false. Object#nil? is a good example. In fact, Object has a lot of good examples of truthiness checks.

like image 80
Jeremiah Peschka Avatar answered Oct 23 '22 10:10

Jeremiah Peschka


It is usual for methods ending with ? to return either true or false but it is not systematic and no core method will assume it.

An example in the core classes is Numeric#nonzero? which never returns true or false.

42.nonzero? # => 42

The library Set has add? and delete? too. I wish Enumerable#one? returned nil or false to distinguish cases where the count is zero from when it is greater than one.

A similar example are the comparison operators (<, >, ...), which usually return only true or false. Here again exceptions exist for Module's operators that will return nil instead when the two modules are not related:

Array > Enumerable  # => false
Array > Fixnum      # => nil
like image 31
Marc-André Lafortune Avatar answered Oct 23 '22 11:10

Marc-André Lafortune


There are two answers to your question, and both are valid:

Technically, anything returning a false or nil value acts as a false boolean when doing a conditional test, just as a non-nil or true value acts as a true. So, the method in question will work correctly for most times you'd want to know if something is an integer.

But stylistically a method that ends with '?' should return either a Boolean true or false and only those.

The method in question doesn't really play nicely with our expectations and fails the POLS ("principle of least surprise") because you can reasonably expect a Boolean value being returned, and get an integer or a nil. THAT could lead to unpleasant surprises in code when it fails with an unexpected nil or a Fixnum value.

So, while it's a valid method, it's not a good method, and I would have brought it up in a code review. And that leads to a separate discussion of how subtle things like that can enhance or hurt code maintenance, but that's an entirely different discussion.

like image 43
the Tin Man Avatar answered Oct 23 '22 11:10

the Tin Man


I renamed the method in question to remove the ?, which was really not important to the question being answered. Scanning through the core functions that end in ?s, the only ones I spotted that returned data or nil were the add? and delete? methods on Set.

like image 27
glenn mcdonald Avatar answered Oct 23 '22 09:10

glenn mcdonald