Here’s a description of the BasicObject#instance_eval method from the Ruby documentation (with some edits for clarity):
Evaluates the given block within the context of the receiver. In order to set the context, the variable self is set to the receiver while the code is executing, giving the code access to the receiver’s instance variables.
In other words, the instance_eval method assigns self to the receiver in the block, thus providing access to the receiver’s instance variables, public methods, and private methods.
class A def initialize @crunk = 'yeahya' end def grill 'platinum' end private def rapper 'lil john' end end a = A.new a.instance_eval do p self # => #<A:0x007fbf1b3313a0 @crunk="yeahya"> p @crunk # => "yeahya" p grill # => "platinum" p rapper # => "lil john" end
Private methods are accessible whenever an explicit receiver is not required. In the instance_eval block, self is assigned to the receiver, so the implicit self can be relied on and private methods can be called. See this blog post for more information about private methods in Ruby.
instance_eval can be used to modify the instance variables of an object:
obj = Object.new obj.set_instance_variable(:@b, 'bob') obj.instance_eval do @b = 'brain' end obj.instance_variable_get(:@b) # => 'brain'
Methods defined in the instance_eval block are singleton methods and are only accessible by the receiver, not all instances of the class.
obj = Object.new obj.instance_eval do def hi 'objects have feelings too' end end p obj.hi # => 'objects have feelings too' p obj.singleton_methods # => [:hi] Object.new.hi # => NoMethodError: undefined method `hi'
The ability to change the context of a program to a specific object is another powerful feature of the Ruby programming language and is one of the many reasons Ruby is an awesome programming language.