When you get farther upwards the steep hill that is Ruby mastery, you will come across some powerful, yet slightly evil methods: instance_eval and class_eval¹. They allow you to execute code and define methods tied to a specific class, at the same time giving you access to outer scope variables through the Ruby block syntax. Their exact behavior varies, depending on the context they are used in. So what is the difference between all the evals?

¹ Also aliased as module_eval

Eval / Method Definition Comparison

In the following tables, you will find all combinations of defining a method and executing it in a different class context:

Class Scope

Definition Method No eval class_eval instance_eval def instance instance class define_method instance instance instance def self. class class class define_singleton_method class class class

Class-Class Scope ( class << self )

Observations

While class_eval behaves exactly as if it was in no eval-context at all, instance_eval features a notable difference: def inside instance_eval will define methods one class-level higher. So when instance_eval is executed on instances, def will create instance methods instead of singleton methods. And when it is run on classes, def will create class methods instead of instance methods.

Another difference is that while class_eval is defined on Module, instance_eval lives in BasicObject allowing you to use it on any object, not only modules and classes. However, there is a simple way to use class_eval for instances, too. You can explicitly use the object's singleton class ( class << self ), which is a module:

o = Object.new # => #<Object:0x000055b6fdabf1f8> o.singleton_class.class_eval do def m p self end end o.m # => #<Object:0x000055b6fdabf1f8>

Best Practice

Overall, the behavior of instance_eval is rather confusing and my recommendation is to avoid it and always use class_eval . If you do not need closure access, consider using no eval at all.

Reference / Examples: Class-Level Scope

For reference, what follows is a list of snippets illustrating each eval-define combination.

Class / def

Defines method on instance-level

class C def m p self end end C.new.m # => #<C:0x0000556efd3eb1a8>

Class / class_eval + def

Defines method on instance-level

class C class_eval{ def m p self end } end C.new.m # => #<C:0x0000556efd3eb1a8>

Class / instance_eval + def

Defines method on class-level

class C instance_eval{ def m p self end } end C.m # => C

Class / define_method

Defines method on instance-level

class C define_method(:m){ p self } end C.new.m # => #<C:0x0000556efd3eb1a8>

Class / class_eval + define_method

Defines method on instance-level

class C class_eval{ define_method(:m){ p self } } end C.new.m # => #<C:0x0000556efd3eb1a8>

Class / instance_eval + define_method

Defines method on instance-level

class C instance_eval{ define_method(:m){ p self } } end C.new.m # => #<C:0x0000556efd3eb1a8>

Class / def self.

Defines method on class-level

class C def self.m p self end end C.m # => C

Class / class_eval + def self.

Defines method on class-level

class C class_eval{ def self.m p self end } end C.m # => C

Class / instance_eval + def self.

Defines method on class-level

class C instance_eval{ def self.m p self end } end C.m # => C

Class / define_singleton_method

Defines method on class-level

class C define_singleton_method(:m){ p self } end C.m # => C

Class / class_eval + define_singleton_method

Defines method on class-level

class C class_eval{ define_singleton_method(:m){ p self } } end C.m # => C

Class / instance_eval + define_singleton_method

Defines method on class-level

class C instance_eval{ define_singleton_method(:m){ p self } } end C.m # => C

Reference / Examples: Class-Class-Level Scope

Class-Class / def

Defines method on class-level

class C class << self def m p self end end end C.m # => C

Class-Class / class_eval + def

Defines method on class-level

class C class << self class_eval{ def m p self end } end end C.m # => C

Class-Class / instance_eval + def

Defines method on class-class-level

class C class << self instance_eval{ def m p self end } end end C.singleton_class.m #=> #<Class:C>

Class-Class / define_method

Defines method on class-level

class C class << self define_method(:m){ p self } end end C.m # => C

Class-Class / class_eval + define_method

Defines method on class-level

class C class << self class_eval{ define_method(:m){ p self } } end end C.m # => C

Class-Class / instance_eval + define_method

Defines method on class-level

class C class << self instance_eval{ define_method(:m){ p self } } end end C.m # => C

Class-Class / def self.

Defines method on class-class-level

class C class << self def self.m p self end end end C.singleton_class.m # => C

Class-Class / class_eval + def self.

Defines method on class-class-level

class C class << self class_eval{ def self.m p self end end } end C.singleton_class.m #=> #<Class:C>

Class-Class / instance_eval + def self.

Defines method on class-class-level

class C class << self instance_eval{ def self.m p self end } end end C.singleton_class.m #=> #<Class:C>

Class-Class / define_singleton_method

Defines method on class-class-level

class C class << self define_singleton_method(:m){ p self } end end C.singleton_class.m # => C

Class-Class / class_eval + define_singleton_method

Defines method on class-class-level

class C class << self class_eval{ define_singleton_method(:m){ p self } } end end C.singleton_class.m #=> #<Class:C>

Class-Class / instance_eval + define_singleton_method

Defines method on class-class-level

class C class << self instance_eval{ define_singleton_method(:m){ p self } } end end C.singleton_class.m #=> #<Class:C>

Also See

More Idiosyncratic Ruby