0.2 Eval for Instances

Restrictive eval

We learned about eval and its ideas in the last lesson. instance_eval is a similar method on the Object class that takes in Ruby code embedded in a string and two other optional arguments.

One of the major differences between eval and instance_eval is that with instance_eval you have the choice of explicitly handling the context of self. As instance_eval is a method on Object it is scoped by the object you specify.

Example Code:

Output Window

Although this scoping within an object might seem a bit restrictive, it isn't necessarily more secure, as the devil still lies in its ability to evaluate code within a string.

If you look at the above example again, you'll notice that we've ended up defining a class method on Monk. Our method is called instance_eval, so why did it define the method as a class method? Let's go back to what we learned in the Classes lesson from the Ruby Primer.

In Ruby, everything is an object. Classes are objects too. Every class that you define is an instance of the class Class. These classes that have instances as other classes are known as metaclasses or eigenclasses.
Example Code:

Output Window

Therefore, we've ended up creating this method on an object which is an instance of the class Class that in our case is Monk. Hence, the name instance_eval.

And as we know, class methods are called as Monk.method. Class objects are created by calling Monk.new. So the above is equivalent to doing this:

Example Code:

Output Window

Basically instance_eval works by treating the object as it were an instance of something. Implying a self context to the receiving object.

Get your head around this oddity, by solving this exercise.

Output Window

Here's how you can use instance_eval to get access to your class' object data. Instance variables are created when you create a new instance from your class.
Example Code:

Output Window

You get a hold of @zen because now you've instantiated a new object that holds the value of @zen and the context has been set to self.@zen.

Unlike eval, instance_eval can also accept a block instead of a string. If you haven't already, it is advisable to read the Blocks lesson on Ruby Primer before solving the rest of this chapter.

Example Code:

Output Window

Solve this simple exercise by using a block with instance_eval.

Output Window

Singleton methods

We tapped into the instance variable of our class by creating an object and using instance_eval on it. What happens when we add methods to this object?

We know that classes take the job for holding the methods for us. In Ruby, objects also have the ability to have methods. These methods are known as singleton methods, because they are only available to this single instance of the class.

Example Code:

Output Window

Define a singleton method zen on the class Monk that returns 42.

Output Window

Taking it to the next level

Embedded DSLs or Domain Specific Languages are an extension of host languages (Ruby in our case) that allow you to tackle problems in a specific domain.

In this example, we reopen the Symbol class and define a method for which evaluates anything passed into it, only if it is called on the :meditate symbol.

Example Code:

Output Window

We've made a pretty readable, English-like syntax here. Combined with more of Ruby's meta-programming tools, you can create really powerful DSLs that are simultaneously simple to read.

Congratulations, guest!


% of the book completed

or

This lesson is Copyright © 2011-2014 by Sidu Ponnappa and Jasim A Basheer