Last week I discussed the differences between class_eval and instance_eval.
I stated there were two basic rules to follow when choosing which method to use:
- When the object is a class use class_eval, you will typically be using the def keyword
- When the object is an instance use instance_eval
When we use instance_eval to define methods where are the located? The are stored in the instance’s singleton class. I will write more about Ruby’s singleton class in the future, but for now you may want to read Ola Bini’s excellent post on the subject.
Let’s look at an example:
class MyClass; end
my_instance = MyClass.new
my_instance.instance_eval do
# add the method to the instance's singleton class
def foo
"bar"
end
end
puts my_instance.foo # => "bar"
another_instance = MyClass.new
begin
# since the method exists only on the my_instance singleton class, calling
# it on another_instance will raise a NoMethodError exception
puts another_instance.greeting
rescue NoMethodError
puts "The foo method does not exist"
end
What happens when we call instance_eval on Class?MyClass.instance_eval do
def baz
"qux"
end
end
puts MyClass.baz # => "qux"
As you can see it defines a class method. I would argue that you should never use instance_eval on a class (although my last post regarding the subject suggested you could). I feel for a beginner in Ruby it may confuse. Stick to class_eval for class objects, and instance_eval for instances. If you need to dynamically define a class method then use this technique:
MyClass.class_eval do
class << self
# define .quux as a class method
#
def quux
"corge"
end
end
def grault
"garply"
end
end
puts MyClass.quux # => "corge"
puts my_instance.grault # => "garply"