In ruby, is truthiness idiomatic for a method name

2020-06-11 14:35发布

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.

4条回答
成全新的幸福
2楼-- · 2020-06-11 15:17

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.

查看更多
不美不萌又怎样
3楼-- · 2020-06-11 15:24

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.

查看更多
▲ chillily
4楼-- · 2020-06-11 15:33

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
查看更多
时光不老,我们不散
5楼-- · 2020-06-11 15:35

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.

查看更多
登录 后发表回答