Dynamic class modification with class_eval in Ruby


Created by Stan on 07-04-2023


class_eval is a powerful method in Ruby that allows you to define new methods and modify existing ones on an existing class at runtime. In this article, we'll explore class_eval and its various use cases using a comprehensive example.

To use class_eval in Ruby, you call it on a class and pass in a string containing the code you want to evaluate in the context of the class. Here's an example of using class_eval to add a new method to an existing class:

class Book
  def initialize(title, author)
    @title = title
    @author = author
  end
end

Book.class_eval do
  def description
    "#{@title} by #{@author}"
  end
end

book = Book.new("Animal Farm", "George Orwell")
puts book.description #=> "Animal Farm by George Orwell"

class_eval can also be used to define a new class dynamically. Here's an example of using class_eval to define a new class based on user input:

class_eval_string = <<-RUBY
  class #{ARGV[0].capitalize}
    def initialize(name)
      @name = name
    end

    def greet
      "Hello, #{@name}!"
    end
  end
RUBY

Object.class_eval(class_eval_string)

person = Object.const_get(ARGV[0].capitalize).new("Alice")
puts person.greet #=> "Hello, Alice!"

class_eval can also be used to define class-level methods. Here's an example of using class_eval to add a new class-level method to an existing class:

class Book
  def initialize(title, author)
    @title = title
    @author = author
  end

  def self.all
    Book.find(:all)
  end
end

book1 = Book.new("The Hitchhiker's Guide to the Galaxy", "Douglas Adams")
book2 = Book.new("Pride and Prejudice", "Jane Austen")

books = Book.all
puts books.inspect #=> [book1, book2, ...]

In this example, the all method uses a database or storage mechanism to retrieve all the books and return them as an array of Book objects.

class_eval is a powerful method in Ruby that allows you to modify existing classes, create new ones, and define class-level methods dynamically at runtime. By using class_eval, you can make your code more flexible and dynamic.



Related Posts