Ruby’s BasicObject#instance_eval method

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.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s