I’ve got a question regarding the inner workings of extend. Consider the
following code that uses Object#extend twice:
class Klass
def hello(options = {})
p options
end
end
module Mod1
def hello(options = {})
super(options.merge({:mod1 => true}))
end
end
module Mod2
def hello(options = {})
super(options.merge({:mod2 => true}))
end
end
k = Klass.new
k.hello #=> {}
k.extend(Mod1)
k.hello #=> {:mod1=>true}
k.extend(Mod2)
k.hello #=> {:mod2=>true, :mod1=>true}
I was a bit surprised that the second extend didn’t clobber the first.
How is this handled by the Ruby interpreter? Is it creating more than
one eigenclass?
Tom
Justin C. wrote:
module Mod1
first. How is this handled by the Ruby interpreter? Is it creating
-Justin
But the behavior of the modules is that of a subclass (being able to
call super to call a method in Klass). If I were to use include inside
the class definition, then I would indeed get superclass behavior.
Tom
Hi –
On Thu, 20 Jul 2006, Tom W. wrote:
def hello(options = {})
k = Klass.new
eigenclass?
No, it’s just inserting the modules along the method lookup chain.
You can examine it like this:
class << k
p ancestors
end
which gives you:
[Mod2, Mod1, Klass, Object, Kernel]
So Mod2 comes before Mod1, but the class (k’s singleton class) still
has Mod1 mixed in.
David
Tom W. wrote:
def hello(options = {})
k = Klass.new
one eigenclass?
Tom
As I understand it, Ruby adds another “transparent” superclass each time
you use extend or include. You can of course do that as many times as
you want to get all kinds of mix-in functionality. There are some nice
diagrams in the Pickaxe book that show this (I don’t have it with me at
the moment).
-Justin
[email protected] wrote:
end
super(options.merge({:mod2 => true}))
k.hello #=> {:mod2=>true, :mod1=>true}
end
Ah! Have I said I love Ruby today?
Thanks David.
Tom