Is it possible to define class methods within `class_eval`?

999 Views Asked by At

I know it's possible to define instance methods using class_eval. Is it possible to define class methods within the context of class_eval?

2

There are 2 best solutions below

1
On

Yes, it is possible:

class Foo
end

Foo.class_eval do
  def self.bar
    puts "I'm a class method defined using class_eval and self"
  end

  def baz
    puts "I'm an instance method defined using class_eval without self"
  end
end

Foo.bar # => "I'm a class method defined using class_eval and self"

foo = Foo.new
foo.baz # => "I'm an instance method defined using class_eval without self"

As far as I can tell, this is because within class_eval, self is the Foo class, and doing def Foo.bar would create a class method.

0
On
Foo.class_eval do
  ...
end

is identical to:

class Foo
  ...
end

We need Module#class_eval to operate on a variable that holds the name of a class. For example, if:

klass = Foo

you can write:

klass.class_eval do
  ...
end

whereas the keyword class demands a constant.

Here class_eval does two things:

  • it changes self to the value of klass (Foo); and then it
  • "opens" the value of klass (Foo) in the same way the keyword class does.