(think)

An online novel about the Source, the Force, the real life and everything in between...

The Elements of Style in Ruby #8: Know Thy Predicates

I often see people writing code like this:

1
if x % 2 == 0 ...

Obviously Fixnum#even? would have been a better choice:

1
if x.even? ...

There is also Fixnum#odd? if you need to check for odd numbers.

By the way, there is even a Numeric#zero? predicate:

1
2
3
4
if x == 0 ...

# same as the above (provided x is a number)
if x.zero? ...

Personally I feel that x == 0 makes more sense for such simple numeric checks, but zero? is there for those you who think otherwise. x == 0 also has the benefit of being nil safe, but that’s not of significant importance.

The Powerpack library also includes the predicate methods Fixnum#pos? and Fixnum#neg?, which are roughly the same as > 0 and < 0 comparisons.

Another bit of code you’ll often see is:

1
if x > 0 && x < 7 ...

While there is nothing particularly bad about that code, I’d argue that between? makes for a nicer (and more OO) alternative:

1
if x.between?(1, 6) ...

Using a range predicate you can also exclude the end value:

1
2
3
4
if x > 0 && x < 1000 ...

# is the same as
if (1...1000).include?(x) ...

When using predicate methods you should be mindful of nil receivers. That’s generally not a serious issue in practice but still I’d ask you to consider this example:

1
if arr == [] ...

It’s not equivalent to

1
if arr.empty?

Why so? Because arr might be nil. So the equivalent code would be:

1
if !arr.nil? && arr.empty?

Of course checking for nils like this is generally not a good idea, but that’s a discussion for some other time.

On a somewhat related note something.nil? is generally preferred over something == nil. If you’re reasonably sure that something can’t have the value false you can, of course, simplify things even further:

1
if something ...

As usual I’m looking forward to hearing your thoughts here and on Twitter!

Comments