Bird
Raised Fist0
Rubyprogramming~5 mins

Class_eval and instance_eval in Ruby - Time & Space Complexity

Choose your learning style10 modes available
Time Complexity: Class_eval and instance_eval
O(n)
Understanding Time Complexity

When using class_eval and instance_eval, it's important to understand how the time to run these methods grows as the code inside them gets bigger.

We want to know how the number of operations changes when we evaluate code blocks on classes or objects.

Scenario Under Consideration

Analyze the time complexity of the following code snippet.


class MyClass
  def self.add_methods(n)
    n.times do |i|
      class_eval do
        define_method("method_#{i}") { i }
      end
    end
  end
end

MyClass.add_methods(5)
    

This code adds n methods to a class using class_eval inside a loop.

Identify Repeating Operations

Identify the loops, recursion, array traversals that repeat.

  • Primary operation: The loop that runs n times, each time calling class_eval to define a method.
  • How many times: Exactly n times, once per method added.
How Execution Grows With Input

Each time we increase n, the number of method definitions grows linearly.

Input Size (n)Approx. Operations
1010 method definitions
100100 method definitions
10001000 method definitions

Pattern observation: The work grows directly with n. Doubling n doubles the work.

Final Time Complexity

Time Complexity: O(n)

This means the time to run grows in a straight line with the number of methods you add.

Common Mistake

[X] Wrong: "Using class_eval or instance_eval runs instantly no matter how many times."

[OK] Correct: Each time you evaluate code, Ruby runs that code, so more code means more time. The cost adds up with each method defined.

Interview Connect

Understanding how dynamic code evaluation scales helps you write efficient Ruby code and explain your reasoning clearly in interviews.

Self-Check

"What if we replaced class_eval with a single class_eval block that defines all methods inside it? How would the time complexity change?"

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