Why does not support vtables hot swap with a popular language feature?

In object-oriented programming, it is sometimes nice to change the behavior of an already created object. Of course, this can be done using fairly detailed methods, such as a strategy template. However, sometimes it would just be easy to completely change the type of an object by changing the vtable pointer after creating the instance. This would be safe if you were moving from class A to class B:

  • class B is a subclass of class A and does not add any new fields, or
  • class B and class A have the same parent class. Nothing but overriding virtual functions from the parent class. (No new fields or virtual functions.)
  • In any case, A and B must have the same invariants.

This is hacked in the C ++ and D programming languages โ€‹โ€‹because pointers can be arbitrarily dropped, but it is so ugly and hard to follow that I am afraid to do this in code that should be understood by someone else. Why is a higher level method not provided at all?

+4
source share
5 answers

Because the thinking of most language designers is too static.

Although such functions are dangerous in the hands of programmers, they are essential tools for library developers. For example, in Java you can create objects without calling the constructor (yes, you can!), But this power is granted only to library developers. However, many features that library developers will kill in Java may not be available. C #, on the other hand, adds all the dynamic functions to each version. I really look forward to all the amazing libraries that can be built using the upcoming DLR (Dynamic Language Execution).

In some dynamic languages, such as Smalltalk (and also as far as I know Perl and Python, but not Ruby), it is quite possible to change the class of the object. In Pharo Smalltalk, you achieve this with

object primitiveChangeClassTo: anotherObject 

which changes the object class to anotherObject class. Note that this is not the same as object become: anotherObject , which swaps all the pointers of both objects.

+3
source

You can do this in Python by changing the __class__ attribute:

 >>> class A(object): ... def foo(self): ... print "I am an A" ... >>> >>> class B(object): ... def foo(self): ... print "I am a B" ... >>> >>> a = A() >>> a.foo() I am an A >>> a.__class__ <class '__main__.A'> >>> a.__class__ = B >>> >>> a <__main__.B object at 0x017010B0> >>> a.foo() I am a B 

However, in my 12 years of Python programming, I have never used this and have never seen anyone else use it. IMHO there is a huge danger that accidentally using this function will make your code difficult to maintain and debug.

The only situation where I can imagine it is debugging runtime, for example. change an instance of a class whose creation I do not have control in the layout of the object or in the class that was decorated with logging. I would not use it in production code.

+2
source

You can do this in higher-level languages โ€‹โ€‹- see Smalltalk's โ€œBecomeโ€ message. The fact that this function is almost impossible to use correctly even in ST may be the reason that statically typed languages โ€‹โ€‹such as C ++ do not support it.

+1
source

What you say is a monkey fix that is available in several high-level dynamic languages:

Monkey Patch (also spelled monkey-patch, MonkeyPatch) is a way to extend or modify runtime code of dynamic languages โ€‹โ€‹(e.g. Smalltalk, JavaScript, Objective-C, Ruby, Perl, Python, Groovy, etc.) Without changing the source code .

0
source

To rephrase the XoTcl documentation, this is because most languages โ€‹โ€‹that declare "object oriented" are not - they are class oriented. It seems that XoTcl mixins, Ruby mixins, and Perl6 roles provide the functionality you are looking for.

0
source

All Articles