Object Polymorphism

I was reading this blog. And the monster problem caught my attention. I decided to take a stab at solving it. Actually, my solution was immediately obvious to me. I'll share it with you. Incidentally, the author of the blog is very prolific. You'll learn a lot from reading his entries.

The problem is that in order to extend object oriented code without having access to the code, you need to do some ugly coding. Take a look at the OpinionatedELF example. He suggests runtime typing every other object to determine how the Elf will react to the other monsters. Obviously you don't want to do this because you have to add a new line and recompile each time a new monster is added.

My solution was to instead add a name method to each monster. In fact in Python, thanks to powerful introspection, this can be done by adding the name method to the base class only. Thus no monsters need to be touched. Now all the Opinionated Elf has to do is ask the monster who he is by invoking his name method. This is better than using the runtime typing because it removes the dependence, in some sense, from the language. One monster is "talking" to the other instead of the monster relying on the language or the interpreter for the answer. The example is below.

class monster:
    def name(self):
        s = str(self.name)
        return s[14:s.find(".name")]

class orc(monster):

class elf(monster):

class opinionated_elf:
    __likes = {"orc": False,
               "elf": True}
    def do_i_like(self,monster):
        return self.__likes[monster.name()]
print opinionated_elf().do_i_like(orc())
print opinionated_elf().do_i_like(elf())

Notice that when you do it this way the Opinionated Elf can be updated without recompiling any code. The hash table of likes could be read from a file. It could be updated in real-time over the network. The solution is on a slightly higher level of abstraction using inter-object communication instead of object-interpreter communication.

I e-mailed the author, and he told me I had an "eminently reasonable solution", but that I went outside the class model. I didn't quite get that last part. It seems to me that it's still polymorphic given that each monster will respond with its own name. It's just that I've moved the decision into the Elf, where it should be. I believe the idea of message passing was one of the original ideas behind objects. But in any case, it works with virtually no special code. And it's completely extensible.