Forum: Ruby changing superclass

Posted by Nokan Emiro (Guest)
on 2012-12-02 22:57
(Received via mailing list)
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.
Posted by Bartosz DziewoƄski (matmarex)
on 2012-12-02 23:29
(Received via mailing list)
Use modules.

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

-- Matma Rex
Posted by Xavier Noria (fxn)
on 2012-12-02 23:45
(Received via mailing list)
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?
Posted by Nokan Emiro (Guest)
on 2012-12-02 23:48
(Received via mailing list)
Hi,

I really appreciate that you want to save me from myself... :)

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.
Posted by 7stud -- (7stud)
on 2012-12-03 03:42
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 by Nokan Emiro (Guest)
on 2012-12-03 11:47
(Received via mailing list)
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:

> Dog.new.greet
>
Posted by 7stud -- (7stud)
on 2012-12-03 20:03
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 by 7stud -- (7stud)
on 2012-12-03 20:04
....
Posted by Nokan Emiro (Guest)
on 2012-12-03 23:20
(Received via mailing list)
>
> 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...
Posted by Xavier Noria (fxn)
on 2012-12-04 00:32
(Received via mailing list)
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
Please log in before posting. Registration is free and takes only a minute.
Existing account (Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
No account? Register here.