5

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?

Andrew Grimm
  • 78,473
  • 57
  • 200
  • 338

2 Answers2

4

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.

Andrew Grimm
  • 78,473
  • 57
  • 200
  • 338
0
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.
Cary Swoveland
  • 106,649
  • 6
  • 63
  • 100