Albert S. wrote:
BTW, anybody knows what exactly def
does? Until now I thought it does
this:
Lookup the enclosing class (or module) and add the method
to its m_tbl.
Based on Hidetoshi’s code it seems def
does this:
Look at ‘self’. If it’s a class (or a module), add the method
to its m_tbl. If it isn’t, get its singleton and add the method
to its m_tbl.
I believe it’s slightly more complex than that.
In executing code, you’re familiar with the idea of “the current
object”. This is made available as ‘self’.
However there’s also a more hidden concept of “the current class”. It’s
rather difficult to get hold of this, but it’s where def defines
instance methods.
“The current class” is set inside a class … end construct. But as
you’ve found, this starts a new scope. So you can use class_eval
instead, which sets both the current object and the current class.
Compare:
class Foo; end
Foo.instance_eval do
def foo; puts “XXX!”; end
end
Foo.foo # you have made a class method
class Bar; end
Bar.class_eval do
def bar; puts “YYY!”; end
end
Bar.new.bar # you have made an instance method
Anyway, this is moot if you are working with closures, because ‘def’
also starts a fresh scope.
It’s surprising to see that a few “important” libraries are using eval.
ActiveRecord, for example. I wonder why.
‘def’ methods are more efficient at runtime (and also less liable to
unforeseen side-effects), precisely because they do not have access to
outer scopes. If you want to 'def ’ where is dynamic, you
have to use eval.