Extend / instance_eval interactions

Why does instance_eval interfere with extend? Should it? If I remove
instance_eval, or place extend before it, meth1 in Klass is overriden
with meth1 in ExtMod. Ruby 1.6.8 Windows. Thanks,

module ExtMod
def meth1; puts ‘C - ExtMod meth1’; end
def meth2; puts ‘D - ExtMod meth2’; end
end

class Klass
def meth1; puts ‘A - Klass meth1’; end
end

s = "def meth1; puts ‘B - instance_eval meth1’; end"
a=Klass.new
a.meth1 #-> A - Klass meth1
a.instance_eval(s)
a.meth1 #-> B - instance_eval meth1
a.extend(ExtMod)
a.meth1 #-> B - instance_eval meth1
a.meth2 #-> D - ExtMod meth2

  • Jim Davis -

Why does instance_eval interfere with extend? Should it? If I remove
instance_eval, or place extend before it, meth1 in Klass is overriden
with meth1 in ExtMod. Ruby 1.6.8 Windows. Thanks,

James, I’m not sure but I think it has to do with chaining of modules
and singleton classes. See below:

module ExtMod
def meth1; puts ‘C - ExtMod meth1’; end
def meth2; puts ‘D - ExtMod meth2’; end
end

class Klass
def meth1; puts ‘A - Klass meth1’; end
end

s = “def meth1; puts ‘B - instance_eval meth1’; end”
a=Klass.new

Here a is of class Klass:

a
Klass (meth1)

a.meth1 #-> A - Klass meth1
a.instance_eval(s)

This creates the singleton class of a, a class that holds a’s own
methods. This class comes before all other classes a inherits from:

a
Singleton class (meth1)
Klass (meth1)

so whenever you call a.meth1, you get meth1 of the singleton class.

a.meth1 #-> B - instance_eval meth1
a.extend(ExtMod)

Now you add ExtMod to the list of a’s ancestors, again AFTER the
singleton class:

a
Singleton class (meth1)
ExtMod (meth1, meth2)
Klass (meth1)

When you call a.meth1, you still get meth1 of the singleton class,
although you included ExtMod after creating the singleton class.

a.meth1 #-> B - instance_eval meth1
a.meth2 #-> D - ExtMod meth2

HTH

Regards,
Pit

···

On 12 Mar 2003 at 6:12, James Davis wrote: