Keeping Ruby DRY

Two ways of doing so

We all know the DRY acronym: Don’t Repeat Yourself

When you’re first learning to program (as I was two years ago) this was THE furthest thing from my mind. The goal was to make functional code first and then start looking at efficiency, clarity, and code cleanliness. You get to the point though, where that approach just does not cut it anymore.

It can be difficult to continuously strive for reduced code duplication under tight deadlines for complicated projects, however it is definitely cost effective to do so. The more time you spend DRYing your code now, the less time you spend debugging later. Since you tend to learn more while editing than writing the initial code, I see this as a win/win.

1. included

What is it?: A callback invoked when a module is included within another class or module
Why does it keep Ruby DRY?: It allows you to share code via a module

module LogState
def self.included(base)
base.after_save :log_state
end
  def log_state
puts "I am logging the state of #{self.class.name}"
end
end
class User < ActiveRecord::Base
include LogState
end
class Visitor < ActiveRecord::Base
include LogState
end

Now users and visitors can share the same callback!

2. define_singleton_method

What is it?: A method used to define a singleton method
Why does it keep Ruby DRY?: It allows you to execute similar code with less clutter.

class Email
def self.send_mailer(email)
define_singleton_method(email.to_sym) do |email_data = {}|
puts “I’m sending an email with #{email_data} as content”
end
end
  %w(
welcome_email
forgot_password_email
order_confirmation_email
).each { |email| self.send_mailer(email) }
end
Email.welcome_email({user_id: 1, coupon: “XXXXX”})

The example above shows how you can send similar types of emails, without explicitly defining how to do so for each and every one.

*One caveat is that this approach is only as concise as you keep it. If you know your email template list will grow indefinitely than the above may not be the best way to implement your email hooks

That’s what I’ve got! What are some ruby techniques you use to reduce code duplication?