DEV Community

Matthew
Matthew

Posted on

My first go at Metaprogramming

I have been a Rails programmer for the past 3 years after transitioning from PHP and Laravel.
So for part of the last 3 years, I had been programming Rails but in a PHP way. I had been trying to get a deeper understanding of things and how to do things better. I recently picked up and read Metaprogramming Ruby 2; Program like the Ruby Pros. Which contains some interesting ideas especially if you have never done this before.

I have recently started a new job that allows me to be more creative with how I solve problems, one of the tasks that I have picked involves handling daily cut-offs for orders.

I had in my head a plan that I wanted a class that I could call with methods e.g after_monday_cutoff? The old me would have written these methods by hand individually.

But I took the chance to look at how this could be done dynamically. This may not be the correct or best way of doing this so please let me know if it can be refactored.

I first created a class that sets a CUT_OFF constant from the setting yml. I am doing to_i here as it is a string.

I then use an array of days which I go over each and pass the day to the defined_method which will then create a method for each of the days

class Cutoff
  class << self
    CUT_OFF = Settings.cut_off.to_i
    %w[monday tuesday wednesday thursday friday saturday sunday].each do |day|
      define_method "after_cutoff_on_#{day}?" do
        now = Time.zone.now
        (now.send("#{day}?") && now.hour >= CUT_OFF)
      end
    end

    %w[monday tuesday wednesday thursday friday saturday sunday].each do |day|
      define_method "before_cutoff_on_#{day}?" do
        now = Time.zone.now
        (now.send("#{day}?") && now.hour < CUT_OFF)
      end
    end
  end
end
Enter fullscreen mode Exit fullscreen mode

This code produces methods like.

def after_cutoff_on_monday?
  now = Time.zone.now
  (now.monday? && now.hour >= CUT_OFF)
end
Enter fullscreen mode Exit fullscreen mode

This is probably not the best use of metaprogramming or indeed the best way of doing this. But it proved to me that something that I thought was complicated can be broken down and used in simpler places and could be a easy in into this new way of programming.

Top comments (0)