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’.