This post explains the difference between
instance_eval methods in Ruby. If you keep getting confused between them when reading or writing Ruby code, it should clarify things a little.
Greeting class, which forms the basis of other examples.
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
This is the same as explicitly defining the
greet method in the
Greeting class. The above code is equivalent to:
- The first benefit of
class_evalis that you can call it on a variable pointing to a class, allowing you to add behavior to a class dynamically.
- 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.
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
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
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.
When the code is executing, the variable
selfis set to the receiving object to set the context, giving the code access to the object’s instance variables and private methods.
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.
class_evalevaluates the string or block in the context of the class, allowing you to reopen the class and define additional behavior on it.
instance_evalevaluates 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.