bernstein7
bernstein7

Reputation: 111

Deep into Ruby class_eval and instance_eval

class_eval and instance_eval are quite predictable in such cases like defining methods. I also understand the difference between class's instance and class's singleton (aka eigenclass).

BUT

I cannot figure out the only thing like following: Let's say, for some strage purposes, we want make existing class to be singleton.

class A; end
class B; end

A.class_eval do
  private :new
end

B.instance_eval do
  private :new
end

in both cases got

NameError: undefined method 'new' for class
Did you mean?  new

yes, I mean exactly this method.

Moreover, these two variants give the same result, like self points at class object in both cases

A.class_eval do
  class << self
    private :new
  end
end

A.new
=> NoMethodError: private method 'new' called for A:Class

B.instance_eval do
  class << self
    private :new
  end
end

B.new
=> NoMethodError: private method 'new' called for B:Class

How come? Can anybody shed the light on this?

Upvotes: 2

Views: 430

Answers (1)

Peter Camilleri
Peter Camilleri

Reputation: 1902

Lets take a peek into what self is here:

class A
  puts self.inspect

  class << self
    puts self.inspect
  end
end

A.class_eval {
  puts self.inspect

  class << self
    puts self.inspect
  end
}

A.instance_eval{
  puts self.inspect

  class << self
    puts self.inspect
  end
}

We get the following output:

A
#<Class:A>
A
#<Class:A>
A
#<Class:A>

The class_eval method is defined for modules (and thus classes) and evaluates within the context of the module (class). The instance_eval method evaluates within the context of a BasicObject. It seems that in these cases the two (three actually) are the same thing.

However, I know for a fact that if methods are created inside the eval block that class_eval creates instance methods and instance_eval creates class methods. There is already an excellent posting for that observation:

Upvotes: 0

Related Questions