Bird
Raised Fist0
Rubyprogramming~10 mins

Class_eval and instance_eval in Ruby - Step-by-Step Execution

Choose your learning style10 modes available
Concept Flow - Class_eval and instance_eval
Start
↓
Call class_eval on Class
↓
Execute block in Class context
↓
Define or modify class methods/variables
↓
Call instance_eval on Object
↓
Execute block in Object's singleton class context
↓
Define or modify singleton methods/variables
↓
End
class_eval runs code inside a class context to add or change instance methods or variables. instance_eval runs code inside a single object's context to add or change its singleton methods or variables.
Execution Sample
Ruby
class Dog
end

Dog.class_eval do
  def bark
    "Woof!"
  end
end

fido = Dog.new
fido.instance_eval do
  def speak
    bark + "!!!"
  end
end

puts fido.speak
This code adds a bark method to Dog class using class_eval, then adds a speak method only to fido instance using instance_eval.
Execution Table
StepActionContextEffectOutput
1Define empty Dog classClass DogDog class created
2Dog.class_eval block startsDog class contextDefines method bark
3Define method barkDog class contextDog instances can bark
4Create fido = Dog.newObject fidoNew Dog instance fido
5fido.instance_eval block startsfido singleton contextDefines method speak only for fido
6Define method speakfido singleton contextfido can speak, other Dogs cannot
7Call fido.speakfido singleton contextCalls bark + '!!!'Woof!!!!
8EndProgram endsOutput printedWoof!!!!
💡 Program ends after printing fido.speak output
Variable Tracker
VariableStartAfter class_evalAfter instance_evalFinal
DogClass definedMethod bark addedNo changeClass with bark method
fidoUndefinedUndefinedMethod speak added to fido onlyDog instance with speak and bark methods
Key Moments - 2 Insights
Why does fido have speak method but other Dog instances do not?
Because speak is defined inside fido.instance_eval block, it adds speak only to fido's singleton class, not to Dog class itself (see execution_table step 5 and 6).
What does class_eval do differently than instance_eval here?
class_eval runs code inside the Dog class context, adding methods to all Dog instances (step 2 and 3), while instance_eval runs code inside a single object's context, adding methods only to that object (step 5 and 6).
Visual Quiz - 3 Questions
Test your understanding
Look at the execution_table at step 3, what method is added to Dog class?
Abark
Bspeak
Cspeak and bark
DNo method added
💡 Hint
Check the 'Effect' column at step 3 in execution_table
At which step does fido gain the speak method?
AStep 2
BStep 4
CStep 6
DStep 7
💡 Hint
Look at the 'Action' and 'Effect' columns around steps 5 and 6
If we create another Dog instance named rover after instance_eval, does rover respond to speak?
AYes, because speak is added to Dog class
BNo, because speak is added only to fido's singleton class
CYes, because instance_eval affects all instances
DNo, because speak is a private method
💡 Hint
Refer to variable_tracker row for fido and Dog, and execution_table steps 5-6
Concept Snapshot
class_eval runs code inside a class to add or change methods for all instances.
instance_eval runs code inside a single object to add or change methods only for that object.
Use class_eval to add methods to a class.
Use instance_eval to add methods to one object.
Methods added by instance_eval are not shared by other instances.
Full Transcript
This visual execution shows how Ruby's class_eval and instance_eval work. First, an empty Dog class is defined. Using class_eval, a bark method is added to Dog class, so all Dog instances can bark. Then, a Dog instance named fido is created. Using instance_eval on fido, a speak method is added only to fido's singleton class, so only fido can speak. When fido.speak is called, it uses bark plus exclamation marks. Other Dog instances do not have speak method. The execution table traces each step, showing context and effects. Variable tracker shows Dog class gains bark method after class_eval, and fido gains speak method after instance_eval. Key moments clarify why speak is only for fido and difference between class_eval and instance_eval. The quiz tests understanding of when methods are added and to which objects. The snapshot summarizes usage: class_eval for class-wide changes, instance_eval for single object changes.

Practice

(1/5)
1. What is the main difference between class_eval and instance_eval in Ruby?
easy
A. class_eval and instance_eval both change the whole class.
B. instance_eval changes the class and affects all instances; class_eval changes only one object.
C. class_eval changes the class and affects all instances; instance_eval changes only one object.
D. class_eval and instance_eval both change only one object.

Solution

  1. Step 1: Understand class_eval behavior

    class_eval opens the class and changes it, so all instances see the change.
  2. Step 2: Understand instance_eval behavior

    instance_eval runs code in the context of a single object, changing only that object.
  3. Final Answer:

    class_eval changes the class and affects all instances; instance_eval changes only one object. -> Option C
  4. Quick Check:

    class_eval = class-wide, instance_eval = single object [OK]
Hint: class_eval affects all objects; instance_eval affects one [OK]
Common Mistakes:
  • Confusing which method affects the class vs. single object
  • Thinking both methods change the whole class
  • Assuming instance_eval changes all instances
2. Which of the following is the correct syntax to add a method greet to class Person using class_eval?
easy
A. Person.class_eval { def greet; 'Hi'; end }
B. Person.instance_eval { def greet; 'Hi'; end }
C. Person.class_eval def greet; 'Hi'; end
D. Person.instance_eval def greet; 'Hi'; end

Solution

  1. Step 1: Recall correct block syntax for class_eval

    class_eval takes a block with method definitions inside curly braces or do-end.
  2. Step 2: Check method definition placement

    Method greet must be defined inside the block passed to class_eval.
  3. Final Answer:

    Person.class_eval { def greet; 'Hi'; end } -> Option A
  4. Quick Check:

    class_eval uses block with method defs [OK]
Hint: Use curly braces or do-end block with class_eval [OK]
Common Mistakes:
  • Omitting braces or block for class_eval
  • Using instance_eval instead of class_eval for class methods
  • Writing method defs outside the block
3. What will be the output of this Ruby code?
class Dog
  def initialize(name)
    @name = name
  end
end

fido = Dog.new('Fido')
fido.instance_eval { def speak; "Woof! I'm #{@name}"; end }
puts fido.speak

rex = Dog.new('Rex')
puts rex.respond_to?(:speak)
medium
A. Woof! I'm Fido false
B. Woof! I'm Fido true
C. NoMethodError for fido.speak
D. Woof! I'm Fido NoMethodError for rex.speak

Solution

  1. Step 1: Understand instance_eval adds method to one object

    The speak method is added only to fido, not to other Dog instances.
  2. Step 2: Check outputs

    fido.speak prints "Woof! I'm Fido". rex.respond_to?(:speak) returns false because rex has no speak method.
  3. Final Answer:

    Woof! I'm Fido false -> Option A
  4. Quick Check:

    instance_eval adds method to one object only [OK]
Hint: instance_eval adds method to one object only [OK]
Common Mistakes:
  • Assuming all instances get the new method
  • Expecting true for rex.respond_to?(:speak)
  • Confusing instance_eval with class_eval
4. Identify the error in this code snippet:
class Cat
end

kitty = Cat.new
kitty.class_eval { def meow; 'Meow!'; end }
puts kitty.meow
medium
A. No error; outputs 'Meow!'
B. NoMethodError because class_eval is called on instance
C. SyntaxError due to missing block
D. RuntimeError because method already exists

Solution

  1. Step 1: Check receiver of class_eval

    class_eval is a method of Class, not of instances; calling it on an instance raises NoMethodError.
  2. Step 2: Verify execution

    Since kitty is an instance, kitty.class_eval raises NoMethodError; thus, puts kitty.meow is not reached.
  3. Final Answer:

    NoMethodError because class_eval is called on instance -> Option B
  4. Quick Check:

    class_eval is a Class method, not instance method [OK]
Hint: class_eval is called on classes, not instances [OK]
Common Mistakes:
  • Thinking class_eval can be called on instances
  • Expecting NoMethodError for instance.class_eval
  • Confusing class_eval usage with class-only restriction
5. Given this code, what will be the output?
class Car
  def initialize(model)
    @model = model
  end
end

car1 = Car.new('Toyota')
car2 = Car.new('Honda')

Car.class_eval do
  def info
    "Model: #{@model}"
  end
end

car1.instance_eval do
  def info
    "Special Model: #{@model.upcase}"
  end
end

puts car1.info
puts car2.info
hard
A. Special Model: TOYOTA Special Model: HONDA
B. Model: Toyota Model: Honda
C. Model: Toyota Special Model: HONDA
D. Special Model: TOYOTA Model: Honda

Solution

  1. Step 1: Understand class_eval adds method to all instances

    info method added by class_eval returns "Model: #{@model}" for all cars.
  2. Step 2: Understand instance_eval overrides method for one object

    car1.instance_eval redefines info only for car1, returning uppercase model with "Special Model:" prefix.
  3. Step 3: Check outputs

    car1.info prints "Special Model: TOYOTA"; car2.info prints "Model: Honda".
  4. Final Answer:

    Special Model: TOYOTA Model: Honda -> Option D
  5. Quick Check:

    class_eval affects all; instance_eval overrides one [OK]
Hint: instance_eval overrides method only on one object [OK]
Common Mistakes:
  • Assuming instance_eval changes all instances
  • Expecting both outputs to be 'Special Model'
  • Confusing which method is called on which object
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard