Sometimes you are coding a template and you need to refer to the same method chain over and over. For example, you’re coding a template that summarizes activity on recent messages. You iterate through a block of messages, and for each message you want to display some information pertaining to the last comment. You could do it like this:

<div class="active_messages">
  <% @active_messages.each do |message| %>
    <h1><%= message.title %></h1>
    <div class="latest_comment">
      <div class="avatar">
        <%= avatar_for(message.comments.last.creator) %>
      </div>
      Latest comment <%= time_ago_in_words(message.comments.last.created_at) %> ago by <%= message.comments.last.creator.full_name %>
    </div>
  <% end %>
</div>

Everything inside of div.latest_comment deals with the exact same comment, but we have to use a method chain to get the comment each time (message.comments.last).

One solution is to set a local variable inside the iterating block with the knowledge that the variable will be reset after each iteration:

<div class="active_messages">
  <% @active_messages.each do |message| %>
    <h1><%= message.title %></h1>
    <% comment = message.comments.last %>
    <div class="latest_comment">
      <div class="avatar">
        <%= avatar_for(comment.creator) %>
      </div>
      Latest comment <%= time_ago_in_words(comment.created_at) %> ago by <%= comment.creator.full_name %>
    </div>
  <% end %>
</div>

One on hand, this is better because the methods called on `comment` are easier to scan. The whole div.latest_comment is more readable without the repeated method chain. On the other hand, setting a local variable is bad style. The local variable assignment creates state without explicitly showing where that state applies. It feels a little too PHP for my taste.

A better approach is to use the `tap` method to scope a variable to a block:

<div class="active_messages">
  <% @active_messages.each do |message| %>
    <h1><%= message.title %></h1>
    <div class="latest_comment">
      <% message.comments.last.tap do |comment| %>
        <div class="avatar">
          <%= avatar_for(comment.creator) %>
        </div>
        Latest comment <%= time_ago_in_words(comment.created_at) %> ago by <%= comment.creator.full_name %>
      <% end %>
    </div>
  <% end %>
</div>

The `tap` block shows exactly where the scope of the assignment starts and ends. I like how the template explicitly says “now we are going to deal with a comment in the following section, and this is the comment we are working with.”

I just hit on this pattern today while working on a feature and I think it’ll come in handy in the future.