How to Use instance_exec in Ruby on Rails

Ruby is known for its flexibility and powerful metaprogramming capabilities. One such method that often comes up in Ruby development, particularly in Ruby on Rails applications, is [instance_exec](https://ruby-doc.org/3.2.0/BasicObject.html#method-i-instance_exec). It allows developers to execute a block of code within the context of an object’s instance, making it extremely useful for dynamically executing code within objects without exposing unnecessary details or methods.

What is instance_exec?

instance_exec is a Ruby method that belongs to the Object class, which means every Ruby object has access to it. Its primary role is to evaluate a given block in the context of an object’s instance. It takes a block and optional arguments, allowing the block to access instance variables and methods of the object it is executed within.

Here’s the basic syntax:

1
object.instance_exec(arg1, arg2, ...) { |args| ... }

In this syntax:

When to Use instance_exec

The most common scenarios where instance_exec is used include:

Example of instance_exec in Ruby

Let’s look at a simple example of using instance_exec:

1
2
3
4
5
6
7
8
9
10
11
12
class Calculator
  def initialize(a, b)
    @a = a
    @b = b
  end
end

calc = Calculator.new(10, 20)

# Use instance_exec to access @a and @b inside the object context
result = calc.instance_exec { @a + @b }
puts result  # Output: 30

In the above example, we are using instance_exec to access the instance variables @a and @b from within the block passed to instance_exec. Normally, these variables would not be accessible from outside the class, but instance_exec gives us that control.

Practical Use in Ruby on Rails

While you may not use instance_exec frequently in Rails development, it can be highly beneficial in specific cases, such as:

For example:

1
2
3
4
5
6
7
8
9
10
11
12
class Post < ApplicationRecord
  after_save :do_something

  private

  def do_something
    instance_exec(self) do |post|
      # You can dynamically access methods or variables of `post`
      puts "Saved post with title: #{post.title}"
    end
  end
end

Here, instance_exec allows the do_something method to run in the context of the saved Post instance, making it possible to perform actions based on its attributes or behavior.

Caution: Use instance_exec Wisely

While instance_exec is powerful, it’s important to use it carefully. Overusing it can lead to code that’s difficult to understand or maintain. Since it gives access to private methods and instance variables, it can break encapsulation, which may introduce bugs if not handled cautiously. Use it only when it provides clear value and avoid making it a routine practice for everyday coding tasks.