rubyinstance-eval

Why use 'instance_eval' instead of creating a method?


Here's a code sample:

class Book
  def initialize
    @v = "abc"
  end
end

b = Book.new
b.instance_eval do
  def book_name
  end
end

Why do we use instance_eval to create a method (book_name) instead of adding book_name method inside class Book? The method (book_name) created using instance_eval will be accessible only by object b in the case above. Is there any particular use case?


Solution

  • instance_eval is very useful when some kind of metaprogramming is needed, like when defining methods during instance initialization or inside frameworks.

    Why use it? It's usually faster than calling define_method in these cases and, if adding a bunch of methods at the same time, invalidates the method cache just once.

    On your specific example the method is being created only on the b instance, making it what is called a singleton method, meaning it only exists for this particular instance. The author could have used eval but since it evaluate code on a more global scope, it's considered unsafe.

    Edit:

    The same effect would be produced if you defined the method using b as the receiver

    def b.book_name
    end