Changing superclass

Hi metaprogrammers,

Does someone know if it’s possible to dynamically switch superclass, or
change the ancestor chain on an already existing class? (Or if it’s
not,
what are the main reasons for this “restriction”, and are there any
plans to
invent the possibility in 2.0, or so?)

I’ve tried to override the superclass and ancestors methods on a class,
which
is, of course, possible, but this does not change the behaviour of the
objects
of that class.

u.

Use modules.

Or just don’t do that, as it seems like a very bad idea.

– Matma R.

I understand the first and second paragraphs separately, but not
together :).

Maybe you want Module#prepend which is going to be available in 2.0?

Hi,

I really appreciate that you want to save me from myself… :slight_smile:

But in Ruby it is possible to call private methods, you can change
the values of constants, you can read and write instance variables
form outside of an object. You can inherit from standard classes,
what’s more, you can reopen them and add/change/undef methods.
These (and many more) seem to be very bad ideas too. I’m just
curious why I can’t change a classes superclass while I can do
all the other magic.

u.

Hi,

What you do here is inserting a new Module into the ancestors chain.
(The superclass of class Dog doesn’t change, it’s still Animal.) If you
could do the same with a Stuff class (not module), that would be the
right answer to my stupid question.

u.

On Mon, Dec 3, 2012 at 3:43 AM, 7stud – [email protected] wrote:

Dog.new.greet

Nokan E. wrote in post #1087546:

Hi metaprogrammers,

Does someone know if it’s possible to dynamically switch superclass, or
change the ancestor chain on an already existing class?

Sure.

class Animal
def greet
puts “Hi, I’m an Animal.”
end
end

class Dog < Animal
end

Dog.new.greet

–output:–
Hi, I’m an Animal.

module Stuff
def greet
puts ‘Hello there.’
end
end

new_superclass = Stuff
Dog.class_eval(“include #{new_superclass}”)
Dog.new.greet

–output:–
Hello there.

Nokan E. wrote in post #1087612:

Hi,

What you do here is inserting a new Module into the ancestors chain.
(The superclass of class Dog doesn’t change, it’s still Animal.)

If Animal is the superclass of Dog, then why doesn’t Animal’s greet()
method execute?

The ancestry chain cannot be modified except for adding stuff in a
restricted way. That is the way the language works, you cannot insert in
arbitrary places, replace, reorder, or remove. There is no API.

Language designers would know the rationale, I don’t.

Sent from my iPad

If Animal is the superclass of Dog, then why doesn’t Animal’s greet()
method execute?

Because imported modules go right above the current class in the
ancestors
chain, but it does not mean that the imported module becomes a class:

Dog.superclass
=> Animal

Dog.ancestors
=> [Dog, Stuff, Animal, Object, Kernel, BasicObject]

Stuff.class
=> Module

The goal is something like this:

class A; end
class B; end
class C < A; end
C.superclass = B # this is wrong here!

This last line doesn’t work, of course, but my question was how
to achieve something like that what it suggests…