These methods let you add or change code inside a class or an object while the program is running. It helps you customize behavior without changing the original code.
Class_eval and instance_eval in Ruby
ClassName.class_eval do # code to add or change instance methods or variables end object.instance_eval do # code to add or change methods or variables for this object only end
class_eval runs code inside the class context, affecting all instances.
instance_eval runs code inside a single object, affecting only that object.
greet to the Person class using class_eval. All Person objects can use it.class Person end Person.class_eval do def greet "Hello!" end end p = Person.new puts p.greet
shout only to the str object using instance_eval. Other strings won't have it.str = "hello" str.instance_eval do def shout upcase + "!" end end puts str.shout
speak method for all Dog objects by reopening the class with class_eval.class Dog def speak "woof" end end Dog.class_eval do def speak "bark" end end puts Dog.new.speak
This program adds a start method to the Car class using class_eval. So all cars can start.
Then it adds a turbo_boost method only to the car1 object using instance_eval. car2 does not have this method.
class Car end Car.class_eval do def start "Car started" end end car1 = Car.new car2 = Car.new puts car1.start car1.instance_eval do def turbo_boost "Turbo boost activated!" end end puts car1.turbo_boost # car2.turbo_boost # This would cause an error because car2 does not have this method
Use class_eval to change or add methods for all instances of a class.
Use instance_eval to add or change methods for a single object only.
Be careful: changing classes or objects at runtime can make code harder to understand.
class_eval changes the class itself and affects all its objects.
instance_eval changes only one object, not the whole class.
Both help you add or change code while the program runs.
Practice
class_eval and instance_eval in Ruby?Solution
Step 1: Understand
class_evalbehaviorclass_evalopens the class and changes it, so all instances see the change.Step 2: Understand
instance_evalbehaviorinstance_evalruns code in the context of a single object, changing only that object.Final Answer:
class_evalchanges the class and affects all instances;instance_evalchanges only one object. -> Option CQuick Check:
class_eval = class-wide, instance_eval = single object [OK]
- Confusing which method affects the class vs. single object
- Thinking both methods change the whole class
- Assuming instance_eval changes all instances
greet to class Person using class_eval?Solution
Step 1: Recall correct block syntax for class_eval
class_evaltakes a block with method definitions inside curly braces or do-end.Step 2: Check method definition placement
Methodgreetmust be defined inside the block passed toclass_eval.Final Answer:
Person.class_eval { def greet; 'Hi'; end } -> Option AQuick Check:
class_eval uses block with method defs [OK]
- Omitting braces or block for class_eval
- Using instance_eval instead of class_eval for class methods
- Writing method defs outside the block
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)Solution
Step 1: Understand instance_eval adds method to one object
Thespeakmethod is added only tofido, not to other Dog instances.Step 2: Check outputs
fido.speakprints "Woof! I'm Fido".rex.respond_to?(:speak)returns false becauserexhas nospeakmethod.Final Answer:
Woof! I'm Fido false -> Option AQuick Check:
instance_eval adds method to one object only [OK]
- Assuming all instances get the new method
- Expecting true for rex.respond_to?(:speak)
- Confusing instance_eval with class_eval
class Cat
end
kitty = Cat.new
kitty.class_eval { def meow; 'Meow!'; end }
puts kitty.meowSolution
Step 1: Check receiver of class_eval
class_evalis a method of Class, not of instances; calling it on an instance raises NoMethodError.Step 2: Verify execution
Sincekittyis an instance,kitty.class_evalraises NoMethodError; thus,puts kitty.meowis not reached.Final Answer:
NoMethodError because class_eval is called on instance -> Option BQuick Check:
class_eval is a Class method, not instance method [OK]
- Thinking class_eval can be called on instances
- Expecting NoMethodError for instance.class_eval
- Confusing class_eval usage with class-only restriction
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.infoSolution
Step 1: Understand class_eval adds method to all instances
infomethod added byclass_evalreturns "Model: #{@model}" for all cars.Step 2: Understand instance_eval overrides method for one object
car1.instance_evalredefinesinfoonly forcar1, returning uppercase model with "Special Model:" prefix.Step 3: Check outputs
car1.infoprints "Special Model: TOYOTA";car2.infoprints "Model: Honda".Final Answer:
Special Model: TOYOTA Model: Honda -> Option DQuick Check:
class_eval affects all; instance_eval overrides one [OK]
- Assuming instance_eval changes all instances
- Expecting both outputs to be 'Special Model'
- Confusing which method is called on which object
Ready to prove it?
Pass the test and this pattern moves unknown
