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.