--- title: "Practical Uses of Ruby Blocks" date: 2010-10-25T00:00:00+00:00 draft: false canonical_url: https://www.viget.com/articles/practical-uses-of-ruby-blocks/ --- Blocks are one of Ruby's defining features, and though we use them all the time, a lot of developers are much more comfortable calling methods that take blocks than writing them. Which is a shame, really, as learning to use blocks in a tasteful manner is one of the best ways to up your Ruby game. Here are a few examples extracted from a recent project to give you a few ideas. ## `if_present?` Often times, I'll want to assign a result to a variable and then execute a block of code if that variable has a value. Here's the most straightforward implementation: ```ruby user = User.find_by_login(login) if user # ... end ``` Some people like to inline the assignment and conditional, but this makes me ([and Ben](https://www.viget.com/extend/a-confusing-rubyism/)) stabby: ```ruby if user = User.find_by_login(login) # ... end ``` To keep things concise *and* understandable, let's write a method on `Object` that takes a block: ```ruby class Object def if_present? yield self if present? end end ``` This way, we can just say: ```ruby User.find_by_login(login).if_present? do |user| # ... end ``` We use Rails' [present?](http://apidock.com/rails/Object/present%3F) method rather than an explicit `nil?` check to ignore empty collections and strings. ## `if_multiple_pages?` Methods that take blocks are a great way to wrap up complex conditional logic. I often have to generate pagination and previous/next links for JavaScript-powered scrollers, which involves calculating the number of pages and then, if there are multiple pages, displaying the links. Here's a helper that calculates the number of pages and then passes the page count into the provided block: ```ruby def if_multiple_pages?(collection, per_page = 10) pages = (collection.size / (per_page || 10).to_f).ceil yield pages if pages > 1 end ``` Use it like so: ```erb <% if_multiple_pages? Article.published do |pages| %>