class_eval vs. instance_eval in Ruby
Tags: ruby, rails, metaprogramming
Published: 2022-01-15 20:19:49

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0o2pjo8jrib0tcfyh0yb.png)
 
### 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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2xragij0uzt7omvi2eaz.png)

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

![Greeting instance](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iy5euaineszckns41qm3.png)

**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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wsbsf89i3x87hger8ovc.png)

### 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`.

```ruby
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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/urnmxmyzsprjkcwau05q.png)

> 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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r1dowkh5rbcbd6ejtvbx.png)
 
---

### 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 in class_eval vs. instance_eval](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2p1hai1bjeq40fhmq8qr.png)