Recently, I have learned about these two methods in Ruby and find them quite useful. In this post, we will see how to use them with examples.
tap
tap
method helps to perform certain operations while still returning the old object.
['hello', 'world'].join(' ').tap { |message| message.upcase }
# "hello world"
As we can see, tap doesn’t return its result. Instead the object it was called on was returned. This is useful for logging.
then
then
passes the object to the block and return the result from the block
['hello', 'world'].join(' ').then { |message| message.upcase }
# "HELLO WORLD"
tap
method helps to perform actions
tap helps to perform actions on the object and remove intermediate variables.
without tap
def deliver_order(order)
updated_order = order.update(status: :delivered)
notify_user(updated_order)
update_inventory(updated_order)
updated_order
end
with tap
def deliver_order(order)
order
.update(status: :delivered)
.tap { |order| notify_user(order) }
.tap { |order| update_inventory(order) }
end
order = deliver_order(order)
order.status_delivered? # true
Without using the tap method we would need to user intermediate variables and return the updated order at the end.
then
method helps in transformation
Since then returns the result from the block, we can use it to do subsequent operations on the object.
def result
Product
.then(&method(:filter_by_category))
.then(&method(:filter_by_brand))
.then(&method(:filter_by_price_range))
end
private
def filter_by_category(products)
return products unless @category
products.where(category: @category)
end
def filter_by_brand(products)
return products unless @brand
products.where(brand: @brand)
end
def filter_by_price_range(products)
return products if @max_price.blank? && @min_price.blank?
products.where("price >= ? && price <= ?", @min_price, @max_price)
end