Alex Rivera | Logout

How to understand the difference between class_eval() and instance_eval()?

Asked 2009-05-22T23:32:21.487
67
Foo = Class.new
Foo.class_eval do
  def class_bar
    "class_bar"
  end
end
Foo.instance_eval do
  def instance_bar
    "instance_bar"
  end
end
Foo.class_bar       #=> undefined method ‘class_bar’ for Foo:Class
Foo.new.class_bar   #=> "class_bar"
Foo.instance_bar       #=> "instance_bar"
Foo.new.instance_bar   #=> undefined method ‘instance_bar’ for #<Foo:0x7dce8>

Just based on the name of the methods, I would expect class_eval to allow you to add a class method to Foo and instance_eval to allow you to add an instance method to Foo. But they seem to do the opposite.

In the example above if you call class_bar on the Foo class you get an undefined method error and if you call instance_bar on the instance returned by Foo.new you also get an undefined method error. Both errors seem to contradict an intuitive understanding of what class_eval and instance_eval should do.

What is really the difference between these methods?

Documentation for class_eval:

mod.class_eval(string [, filename [, lineno]]) => obj

Evaluates the string or block in the context of mod. This can be used to add methods to a class.

Documentation for instance_eval:

obj.instance_eval {| | block } => obj

Evaluates a string containing Ruby source code, or the given block, within the context of the receiver (obj). In order to set the context, the variable self is set to obj while the code is executing, giving the code access to obj’s instance variables.

Edit
Report

1 Answer

3

instance_eval effectively creates a singleton method for the object instance in question. class_eval will create a normal method in the given class's context, available to all objects of that class.

Here's a link regarding singleton methods and the singleton pattern(non-ruby specific)

answered 2009-05-23T00:10:27.197

Your Answer