class eval and instance eval in Ruby – Meta programming

class_eval

class_eval allows us to define a method within the class outside of its original definition and without reopening the class with the standard syntax. This could be useful when you want to add this method to is not known until runtime.

class Employee
end

# Employee is evaluated as a class

Employee.class_eval do
  def say_hello
    puts 'Hello'
  end
end

e = Employee.new
e.say_hello
=> Hello

Remember that class_eval evaluates Employee as a class and say_hello method is added to it. So it becomes an instance method.


# String is evaluated as a class

String.class_eval do
  def concat_hello
    'Hello! ' + self
  end
end

'Srinidhi'.concat_hello
=> "Hello! Srinidhi"

Again, class_eval evaluates String as a class. We added a method to String class to concat a string ‘Hello!’.

Note: String is a Ruby built-in class.

instance_eval

instance_eval effectively creates a singleton method for the object instance. That means that Student.instance_eval is evaluated in the context of the Student object.

class Student
end

# Student is evaluated as a instance

Student.instance_eval do
  def name
    puts 'I am a Student'
  end
end

Student.name
=> I am a Student

In the above code, Student is evaluated as a instance. In other words, Student is no more a class, in the context of it’s method, it has become an Object or an instance. So name is the method of Student instance. Therefore it can be accessed as Student.name not as Student.new.name.

class Mentor
end

teacher = Mentor.new
teacher_1 = Mentor.new

# teacher is evaluated as a instance

teacher.instance_eval do
  def evaluate
    puts 'Yes I evaluate'
  end
end

teacher.evaluate
=> Yes I evaluate

teacher_1.evaluate
NoMethodError: undefined method `evaluate' for #

In the above code, teacher is instance of class Mentor. instance_eval evaluates teacher as a instance, we add a method evaluate to that teacher instance only. Therefore teacher.evaluate works and teacher_1.evaluate throws an error.

Leave a Reply

Your email address will not be published. Required fields are marked *