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.helloOld 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.countThe 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.titlemodule_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? :kindKey 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?