Instance_eval and class_eval - names got mixed up?

Going through the Ruby P.ming Language text Chapter 8 Reflection
and MetaProgramming. Section 8.2.2 on page 270.

The following paragraph has me puzzled:

“Note the subtle but crucial difference between instance_eval and
class_eval when the code being evaluated contains a method definition.
instance_eval defines singleton methods of the object (and this results
in class methods when it is called on a class object). class_eval
defines regular instance methods.”

Is this not supposed to be the other way around? instance_eval should
define instance methods and class_eval should define class methods. Is
there a catch here? Ruby is supposed to be following principle of least
surprise. I must say I am surprised here, or there is something quite
profound that I don’t get.

Bharat

On Fri, Mar 7, 2008 at 2:06 PM, Bharat R. [email protected]
wrote:

Is this not supposed to be the other way around? instance_eval should
define instance methods and class_eval should define class methods. Is
there a catch here? Ruby is supposed to be following principle of least
surprise. I must say I am surprised here, or there is something quite
profound that I don’t get.

Bharat

It’s the use of the word “instance” here that causes the problem.
Singleton methods are specific to a single instance of an object. An
instance method refers to a method that’s available to every
instance of a class upon their creation. Maybe it should be
singleton_eval and instance_eval, but, see, that doesn’t really make
sense, because that would imply eval being used within the singleton
class of the object. One of those meta-programming language
work-arounds I guess.

Todd

2008/3/7, Bharat R. [email protected]:

Is this not supposed to be the other way around? instance_eval should
define instance methods and class_eval should define class methods. Is
there a catch here? Ruby is supposed to be following principle of least
surprise. I must say I am surprised here, or there is something quite
profound that I don’t get.

No, the book is correct. The “instance” in instance_eval indicates that
you are
evaluating code in the context of one specific instance - if this
instance is a class
object, method definitions happen to define class methods.

instance_eval is defined in Object, so you can use it on any object -
nothing
special about classes here, except that we call singleton methods on
classes “class methods”.

class_eval evaluates code as if it appeared between “class … end”.
And a “def” between “class … end” defines instance methods of the
class.

Stefan

Thanks gentlemen for your responses. It still requires mental gyrations
for me. I honestly think that this one got away from Matz.

Bharat R. wrote:

Thanks gentlemen for your responses. It still requires mental gyrations
for me. I honestly think that this one got away from Matz.

The confusion here is that you’re calling instance eval on a specific
class. In ruby, classes are instances of the Class class (no, that is
not a type). Methods added to your class (the instance of the class
Class) are, in effect, added the the class definition. Below is an
example of using class_eval and instance_eval against a simple class, so
you might find this less confusing.

class Foo
def hi
puts “hi”
end
end
=> nil

foo = Foo.new
=> #Foo:0x3aa250

foo.instance_eval do
?> hi

end
hi
=> nil

Foo.class_eval do
?> def howdy

puts "howdy"

end
end
=> nil

foo.howdy
howdy
=> nil

Hi,

On Sat, Mar 8, 2008 at 8:09 AM, Bharat R. [email protected]
wrote:

Thanks gentlemen for your responses. It still requires mental gyrations
for me. I honestly think that this one got away from Matz.

Perhaps just try to remember that only classes have class_eval, and only
instances (i.e. everything) has instance_eval. Hence, since all objects
could have singleton methods, instance_eval must add methods to the
singleton class, whereas what you put in a class_eval' block is similar to when you use the class’ keyword itself.

Arlen

Bharat R. wrote:

I honestly think that this one got away from Matz.

So you’d want the names of the methods class_eval and instance_eval
to be switched? So that doing “lala”.class_eval would be allowed,
but “lala”.instance_eval would not? I’d find that a bit
counter-intuitive
to be honest.

Bharat R. wrote:

Going through the Ruby P.ming Language text Chapter 8 Reflection
and MetaProgramming. Section 8.2.2 on page 270.

The following paragraph has me puzzled:

“Note the subtle but crucial difference between instance_eval and
class_eval when the code being evaluated contains a method definition.
instance_eval defines singleton methods of the object (and this results
in class methods when it is called on a class object). class_eval
defines regular instance methods.”

Is this not supposed to be the other way around? instance_eval should
define instance methods and class_eval should define class methods. Is
there a catch here?

The catch is that a class is an instance. For a moment, forget that
class_eval even exists. Without that distraction, instance_eval seems
to operate consistently: 1) it creates singleton methods for 'normal
'objects, e.g. mydog which is an instance of a Dog class, and 2) it
creates singleton methods for objects which are instances of the class
Class, i.e. all classes. It just so happens that a singleton method for
a class object is known as ‘class method’.