George Ogata
4/15/2006 5:35:00 AM
"Minkoo Seo" <minkoo.seo@gmail.com> writes:
> In this case,
>
> Foo.instance_eval do
> def bar
> end
> end
>
> defines 'bar' at Foo singletone class while self, which I have been
> thought to be the receiver of def keyword, is Foo. Right? Then, how do
> you know where the method defined by 'def' is generated in general?
>
> Frankly, I've been trying to memorize how to geneate 'instance/class'
> method and want to find some rules for metaprogramming.
I trekked the source the other day to clear this up in my mind, so
I'll offer another explanation, in case anyone's interested.
At any point in any ruby code, ruby has a concept of the "current
object", which is what is referenced by `self', and the "current
class", which is the class that gets a new instance method when you do
`def ... end'. They are orthogonal concepts.
* Inside a class (`class Foo ... end'), the "current object" is Foo,
and the "current class" is also Foo. Hence, `self' refers to the
class, and doing `def ... end' adds to the class.
* At the toplevel, the "current object" is an instance of Object, and
the "current class" is Object. This explains why, at the toplevel,
methods you define become instance methods of Object, but `self' is
NOT the Object class:
irb(main):001:0> self
=> main
irb(main):002:0> self.class
=> Object
If self were the Object class, line 001 would print "Object" and
line 002 would print "Class". So to anyone that says "imagine the
toplevel is wrapped in `class Object; private; ... end'", you're
wrong!
* When you call `foo.instance_eval', the "current object" is set to
`foo', and the "current class" is set to foo's singleton class, then
the block is yielded / string is evalled. Thus, `self' refers to
`foo', while `def ... end' adds to foo's singleton class.
* When you call `Foo.class_eval', the "current object" is set to
`Foo', and the "current class" is set to `Foo', then the block is
yielded / string is evalled. This is just like inside a `class
... end' expression.
I think that's it. Hope it helps.