Telephone iconCall UsTelephone icon0333 0146 683
Our opening hours
Chevron left icon
Tech blog

Demystifying class_eval and instance_eval in Ruby

1-minute read

Cai Gao

26 January 2021

Facebook iconTwitter iconLinkedIn icon

Ruby gives you the ability to modify a class or an object on-the-fly. You may have seen examples of code written like the examples below.

Example 1: instance_eval

person.instance_eval do
  def name
    @name.capitalize
  end
end

Example 2: class_eval

Person.class_eval do
  def name
    @name.capitalize
  end
end

At first glance, the two blocks of code look very similar. But if you look closely, you'll see that the first example is calling instance_eval on person, an instance of the class Person. The second example is calling class_eval on the actual Person class.

So what is the difference, you might ask?

Simply Business technology

Let me illustrate.

Suppose we have the Person class defined and have created two instances of Person: person1 and person2.

class Person
  def initialize(name)
    @name = name
  end
end 

person1 = Person.new("bob")
person2 = Person.new("jane")

Now let’s apply this code:

person1.instance_eval do
  def name
    @name.capitalize
  end
end

What happens when we call person1.name? How about person2.name?

If you guessed person1.name returns “Bob”, then you are correct. But does person2.name return “Jane”?

Let’s see:

irb(main):014:0> person1.name
=> "Bob"

irb(main):015:0> person2.name
=> NoMethodError (undefined method `name' for #<Person:0x00007f9beb9539c0 @name="jane">)

That’s right - instance_eval only evaluates in the context of one object. Only the particular instance that instance_eval is called on is injected with the name method. In this case, person1 has access to the name method, but not person2.

Now you might be tempted to call instance_eval on person2, which will make the name method accessible to person2. But what happens if you have person3 and person4? It doesn’t make sense to duplicate code. We want to make sure that the method is shared by all objects of the Person class.

If you guessed to use class_eval, you're right. class_eval defines an instance method for the class, so that all instances of that class have access to the method. Let’s see:

Person.class_eval do
  def name
    @name.capitalize
  end
end

irb(main):042:0> person1.name
=> "Bob"
irb(main):043:0> person2.name
=> "Jane"
irb(main):044:0> person3 = Person.new("Susan")
=> #<Person:0x00007f9bef866ef0 @name="Susan">
irb(main):045:0> person3.name
=> "Susan"
irb(main):046:0> person4 = Person.new("Mike")
=> #<Person:0x00007f9beb9009a0 @name="Mike">
irb(main):047:0> person4.name
=> "Mike"

All instances of the Person class, new and old, can now call name. Defining a method with class_eval is syntactically the same as defining it in the actual class.

Person.class_eval do
  def name
    @name.capitalize
  end
end

is exactly equivalent to:

class Person
  def name
    @name.capitalize
  end
end

I hope this has helped your understanding of Ruby’s instance_eval and class_eval methods. Just remember that you can only call instance_eval on an object of a class and class_eval on a class. The instance_eval method defines a method for one object only, whereas the class_eval method defines it for ALL objects or instances of a class.

See our latest technology team opportunities

If you see a position that suits, why not apply today?

Find out more

We create this content for general information purposes and it should not be taken as advice. Always take professional advice. Read our full disclaimer

Find this article useful? Spread the word.

Facebook icon
Share
Twitter icon
Tweet
LinkedIn icon
Post

Keep up to date with Simply Business. Subscribe to our monthly newsletter and follow us on social media.

Subscribe to our newsletter

Insurance

Public liability insuranceBusiness insuranceLandlord insuranceTradesman insuranceProfessionals' insuranceNot for profit insuranceRestaurant insuranceCommercial van insuranceInsurers

Address

6th Floor99 Gresham StreetLondonEC2V 7NG

Sol House29 St Katherine's StreetNorthamptonNN1 2QZ

© Copyright 2021 Simply Business. All Rights Reserved. Simply Business is a trading name of Xbridge Limited which is authorised and regulated by the Financial Conduct Authority (Financial Services Registration No: 313348). Xbridge Limited (No: 3967717) has its registered office at 6th Floor, 99 Gresham Street, London, EC2V 7NG.