class_eval vs. instance_eval in Ruby

January 15, 2022   • ruby

This post explains the difference between class_eval and instance_eval methods in Ruby. If you keep getting confused between them when reading or writing Ruby code, it should clarify things a little.

Consider the Greeting class, which forms the basis of other examples.

Greeting class

class_eval

class_eval evaluates the string or block in the context of the class, allowing you to reopen the class and define additional behavior on it.

Creating a method inside the block defines an instance method on the class. All Greeting instances can call greet.

class class_eval

This is the same as explicitly defining the greet method in the Greeting class. The above code is equivalent to:

Greeting instance

Benefits

  1. The first benefit of class_eval is that you can call it on a variable pointing to a class, allowing you to add behavior to a class dynamically.
  2. When using class_eval, the code will fail immediately, if the class doesn’t exist (or if you misspelled the class name). So you can’t accidentally add code to a class that doesn’t exist.

The class_eval method is only available on classes (modules, to be precise). You can’t call it on instances, i.e. instance_name.class_eval doesn’t exist. Ruby throws the error undefined_method class_eval.

instance class_eval

instance_eval

instance_eval evaluates the code in the context of the receiving object. When you call it on a class, e.g. ClassName.instance_eval, the receiving object is the class, which is an instance of Class. For example, Greeting is an instance of Class.

irb(main):043:0> Greeting.class
=> Class

If you create a method inside the block, it defines a class method. It’s associated with the class object but not visible to instances of that class.

class instance_eval

When the code is executing, the variable self is set to the receiving object to set the context, giving the code access to the object’s instance variables and private methods.

Similarly, calling instance_eval on an instance, e.g. instance_name.instance_eval defines a method on that specific instance. No other instances of the class can access that method.

instance instance_eval


Summary

  1. class_eval evaluates the string or block in the context of the class, allowing you to reopen the class and define additional behavior on it.
  2. instance_eval evaluates the string or block in the context of the receiver object, allowing you to run code as if we were inside a method of this object, giving access to its private methods.

Difference