Send — Underrated Spell for Metaprogramming

Lakhveer Singh Rajput
2 min readDec 4, 2023

--

We have always heard about metaprogramming in Ruby, but how we can implement it in our codes is something different. In the previous article, we went through two methods class_eval and instance_eval, which are some ways to implement the metaprogramming in our code. There are many more ways to implement metaprogramming but the Ruby has provided some easier ways to implement it. They are through using methods such as — send, method_missing, and define_method. Let us have a look at them.

Send — The caller method

The send method is used to invoke the other methods by passing its name as an argument, and other arguments as follows. Now, a question may arise if we can simply call any method on the object just with the ‘.’ then why need to invoke this through send? Let's see the syntax then we will have the answer for this question.

class Laptop
def which_brand(brand)
puts "#{brand}"
end
end

laptop = Laptop.new
laptop.send(:which_brand, "Macbook")
#Macbook

So, why need a send method if we can simply call any method of the object? Now, we are making a class for the Order which has a different method for their status. Another class UserOrder will initialize Order for the user with the status.

class Order
def initialize(status)
@status = status
end
def out_of_delivery
puts "Out of Delivery"
end

def in_transition
puts "In Transition"
end

def delivered
puts "Delivered"
end

def approved
puts "approved"
end

def status
@status
end
end

class UserOrder
def initialize(order)
@order = order
@status = @order.status
end

def order_status
if @status == "out_of_delivery"
@order.out_of_delivery
elsif @status == "in_transition"
@order.in_transition
elsif @status == "delivered"
@order.delivered
elsif @status == "approved"
@order.approved
end
end
end

UserOrder.new(Order.new("out_of_delivery")).order_status
#Out of Delivery

This is a simple example where the User Order status is displayed. Now have a look at changing it with the send method and try this again.

class UserOrder
def initialize(order)
@order = order
@status = @order.status
end

def order_status
@order.send(@status)
end
end


UserOrder.new(Order.new("in_transition")).order_status
#In Transition

Wow, we had changed the whole need for the if-else loop in the order_status method.

To be continued

We had given priority to the send method as it has been always underrated in writing the codes. Suppose many times in our code we require the worker to perform a certain job but with different models and the same set of attributes. We would go for the send method such that it will be DRY( Don’t Repeat Yourself), which means you have the same worker for both jobs. The send method is more magical than it seems. We will continue with method_missing and define_method in the upcoming stories.

--

--

Lakhveer Singh Rajput

Ruby on Rails enthusiast, book lover and DevOps explorer. Follow me for insights on coding, book recommendations, and bridging development with operations.🚀📚