---
title: any? != ! empty?
teaser:
tags: web,rails
author: Jared Carroll
published_on: 2007-07-05
---

A common Ruby/Rails idiom used in views looks like the following:

```erb
<% if @posts.empty? -%>
  There are no posts.
<% else -%>
  <ul>
    <%= render :partial => 'post', :collection => @posts -%>
  </ul>
<% end -%>
```

Say that was from `/posts` or `PostsController#index`.

Alternatively, I've seen this:

```erb
<% if @posts.any? -%>
  <ul>
    <%= render :partial => 'post', :collection => @posts -%>
  </ul>
<% else -%>
  There are no posts.
<% end -%>
```

Testing for the positive first instead of the negative first.

The following is also valid, but its not legal in my book because it's trash:

```erb
<% unless @posts.empty? -%>
  <ul>
    <%= render :partial => 'post', :collection => @posts -%>
  </ul>
<% else -%>
  There are no posts.
<% end -%>
```

I bet that took a couple takes before you got that.  'unless ... else' is a
terrible Ruby construct.

Sorry got sidetracked on my 'unless ... else' hate.

Take a look at the following Ruby:

```ruby
[1, 2].any? => true
[nil, nil].any? => false

[1, 2].empty? => false
[nil, nil].empty? => false
```

I never liked using `#any?` without a block, it felt/feels too strange.  Now if
you don't pass `#any?` a block you get a default block, which looks like this:

```ruby
[1, 2].any? {|each| each}
```

Now `#any?` is a method that asks is there anything in this collection that's
true?.  In Ruby, the existence of an object is considered true; so calling
`#any?` without a block is saying is there something that's not nil or false in
this collection?.

So the view code from above:

```erb
<% if @posts.any? -%>
  <ul>
    <%= render :partial => 'post', :collection => @posts -%>
  </ul>
<% else -%>
  There are no posts.
<% end -%>
```

Isn't it really saying is there anything in this posts collection? Because that
collection could contain `nil`.  And `nil` is an object, its an instance of
`NilClass`; so the collection actually does have something in it.  Using `#any?`
is this context, basically as way of saying 'not empty', is incorrect because
it's relying on Ruby's ugly feature of 'object existence implies truth' to test
if there's anything in a collection.

The correct code, when testing the positive first, should be:

```erb
<% if ! @posts.empty? -%>
  <ul>
    <%= render :partial => 'post', :collection => @posts -%>
  </ul>
<% else -%>
  There are no posts.
<% end -%>
```
