Adding Methods & Monkey Patching


Do you ever want your own methods in Ruby's libraries? Sometimes it comes to me that "what if I have xxx method and it will be great." In fact, since Ruby offers a way to add or overwrite methods in existing libraries, it is easy to do it in Rails.

One good example is when we're checking if a Date is weekday or weekend. It's great that we're able to use #wday and get the weekday of a specific date.

date = Date.new(2016, 4, 11)
date.wday # => 1

So we can define two methods that checks if a date is weekday or weekend.

def weekend?(date)
  [6, 0].include?(date.wday)
end

def weekday?(date)
  !weekend?(date)
end

date = Date.new(2016, 4, 11)
weekday?(date) # => true

However, this is very limited because we still have to use an argument in the method. We can put it in the Date class then we can get rid of the argument.

class Date
  def weekend?
    [6, 0].include?(self.wday)
  end

  def weekday?
    !weekend?
  end
end

date = Date.new(2016, 4, 11)
date.weekday? # => true

It looks a lot better. But where should we put it in a Rails project? The best place is /lib since it serves to hold anything that is not domain-specific in your project. Creating a lib/patch directory and puts a date.rb file like:

- lib
  - patch
    - date.rb

And then we load the files every time we start the Rails server or console. In config/initializers we create a patch.rb file that looks like:

Dir["#{Rails.root}/lib/patch/**/*.rb"].each {|file| require file }

And we're done! Any other patch we want to create for other class or libraries can be put in lib/patch directory too.

Reference

What code goes in the lib/ directory?