Blog

Saturday, August 14, 2010

When to use Ruby's class_eval vs. instance_eval

When to use class_eval vs instance_eval? Here are some basic rules to follow:

  1. When the object is a class use class_eval, you will typically be using the def keyword
  2. When the object is an instance use instance_eval

There is an important subtle difference between the two.

  • class_eval changes self and the current class
  • instance_eval only changes self

If you don't need to use def then what should use use? Well you could use MyClass.instance_eval. But as Paolo Perrotta states from Metaprogramming Ruby:

"…pick the method that best communicates our intentions."
class Book
  
  # define a class instance variable
  #
  @books_published = 0

  # define the attr_accessor as a class method
  #
  class << self
    attr_accessor :books_published
  end
    
  def initialize(title)
    @title = title
    Book.books_published =+ 1
  end
end

b = Book.new("Metaprogramming Ruby")

Book.class_eval do
  def introduction
    "Thank you for reading #{@title}"
  end
  
  private
  
  def units_sold
    100_000
  end
end

b.instance_eval do
  puts @title # access an instance variable => Metaprogramming Ruby
  puts units_sold # send a message to a private method => 100000
end

puts b.introduction # => Thank you for reading Metaprogramming Ruby

# I don't care if this is a class or an instance
Book.instance_eval do
  puts @books_published # => 1
end

Please note this blog is no longer maintained. Please visit CivilCode Inc - Custom Software Development.