๐ŸŽ“ A1Learner
๐Ÿ”
0 of 28 lessons completed

Ruby Class Eval

class_eval reopens a class from outside its own definition. The block it runs adds methods as if it were written inside the class body.

Adding a method from outside

The Greeter class starts empty. A class_eval block defines hello inside it, and a fresh object answers the new method.

class Greeter
end
Greeter.class_eval do
  def hello
    "Hello from Greeter"
  end
end
puts Greeter.new.hello

Old objects gain the methods

The counter object exists before the class_eval call. The block adds bump and count, and the older object answers both new methods.

class Counter
  def initialize
    @count = 0
  end
end
counter = Counter.new
Counter.class_eval do
  def bump
    @count = @count + 1
  end
  def count
    @count
  end
end
counter.bump
counter.bump
puts counter.count

The string form

class_eval can take a string holding the code instead of a block. The string here defines the title method on the Song class.

class Song
end
code = "def title
  'Sunrise'
end"
Song.class_eval code
puts Song.new.title

module_eval on a module

module_eval works on a module the same way. The method it defines becomes available to any class that includes the module.

module Shout
end
Shout.module_eval do
  def shout(text)
    text.upcase
  end
end
class Person
  include Shout
end
puts Person.new.shout "hey"

Example

class Plant
end
Plant.class_eval do
  def kind
    "fern"
  end
end
puts Plant.new.kind
puts Plant.new.respond_to? :kind

Key points

  • class_eval runs a block with the class as self.
  • Methods defined in the block become instance methods of the class.
  • class_eval also accepts a string of code instead of a block.
  • module_eval is the same tool used on a module.
  • Objects created before the call gain the new methods too.

In this example, a class_eval block adds the kind method to the Plant class. A plant object answers the method with its word. The object also answers true when asked about the new name.

Try it Yourself

Edit the code, then press Run.

Running is simulated

Exercise

A class_eval block defines greet on the class Song. What does Song.new.respond_to?(:greet) return?