current object and current class

Everything is an object in Ruby, there is an current object and current class referred to in every line of code. We use self to refer to current object (there is no keyword for current class).

When call a method on an object, self(current object) is the receiver of the method. In a class definition, self(current object) is the class itself.

Though there is no keyword for current class, it’s easy to refer to as long as we know what is our current object.

class_eval

Module#class_eval is used for modifying current class. It’s commonly used when we don’t know the exact name of class we want to refer to. For example,

def add_method_to(my_class)
  my_class.class_eval do
    def foo
      puts 'foo'
    end
  end
end
			
add_method_to(String)
"bar".foo
#=> "foo"

One example in Rails is putting common code for several models (just like what model conern does). For example, I want to add common validations for my models, I can create a module and use class_eval to add methods in classes that include it. In order to get that class, we need a hook method self.included, and put class_eval part inside this method.

module SomeCommonModule
  def self.included(base)
    base.class_eval do
      validates_presence_of :balabalabala
    end
  end
end

instance_eval

instance_eval is used for modifying current object (self), it breaks encapsulation, be careful with it.

An example is to change instance variable of an object:

class Foo
  def bar
    @bar = "bar"
  end
end

foo = Foo.new
foo.bar
puts foo.instance_eval { @bar }
 #=> "bar"
foo.instance_eval { @bar = "bbbbar" }
puts foo.instance_eval { @bar }
 #=> "bbbbar"