Ruby: instance_eval

Adding methods to an instance “on-the-fly” is a pretty common pattern in Ruby (activerecord, activesupport, etc..).

To do so, we can use the BasicObject#instance_eval methods.

Adding methods

In Ruby, when we want to add a method to an instance we can use the BasicObject#instance_eval method. This method accepts a String or a block as argument

The call to a.instance_eval(array_second) adds the method second to the variable a — which is an instance of Array — by passing a String that will be evaluated in the context of the instance a.

The call to str.instance_eval with a block will evaluate the content of the block in the context of str — which is an instance of String.

Here it’ll add a /(delimiter)method — that we can use as operator — to thestr instance.

NB: feel free to read this article about class_eval vs module_eval for further information

access inner variables

Another feature of the instance_eval method is its ability to access inner variables

Here, we access the @email inner variable by calling it as a String argument of u.instance_eval as well as inside a block that we pass to instance_eval.

This is possible because instance_eval is executed in the context of the receiver object — in this case, the u variable.

This means that all the code passed as argument will be executed in the scope of the instance of User named u.

Bypassing Method Access Control

By using instance_eval, This is possible to call a private or a protected method of a given object from outside of this one.

Here, we access the User#secret_key private method by calling it as a String argument of u.instance_eval as well as inside a block that we pass to instance_eval.

NB: feel free to read this article about Private & Protected methods if the object message and method access control concepts are unfamiliar to you

Voilà !

May I have your attention please 🎤🎤

Feel free to subscribe here: www.rubycademy.com


Thank you for taking the time to read this post :-)

Feel free to 👏 and share this Medium post if it has been useful for you.

Here is a link to my last medium post: Ruby Bitwise Operators.