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 Rex

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?

···

On Sun, Dec 2, 2012 at 10:55 PM, Nokan Emiro <uzleepito@gmail.com> wrote:

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.

Nokan Emiro 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.

···

--
Posted via http://www.ruby-forum.com/\.

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.

···

On Sun, Dec 2, 2012 at 11:20 PM, Bartosz Dziewoński <matma.rex@gmail.com>wrote:

Use modules.

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

-- Matma Rex

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 -- <lists@ruby-forum.com> wrote:

class Animal
  def greet
    puts "Hi, I'm an Animal."
  end
end

class Dog < Animal
end

Dog.new.greet

module Stuff
  def greet
    puts 'Hello there.'
  end
end

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

Nokan Emiro 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?

···

--
Posted via http://www.ruby-forum.com/\.

7stud -- wrote in post #1087690:

···

Nokan Emiro 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? ancestors() and superclass() don't allows tell the truth.

--
Posted via http://www.ruby-forum.com/\.

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...

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

On 3 Dec 2012, at 23:19, Nokan Emiro <uzleepito@gmail.com> wrote:

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...