Wednesday, March 8, 2006

Metaclass Madness

Okay. For future reference, you might want to try to keep me away from advanced programming language features. First I found out about Python's descriptors. Ok. They're simple enough. But that lead me to metaclasses. I didn't understand them so I read the metaclass book. Then I looked into ruby's metaprogramming, and I wondered how I could achieve some of the cool things I can do in rails using python. It's certainly not as clean as, say, attr_accessor :foo, :bar, :baz; but I came up with a very simple metaclass to let me do something like:


class blah(AutoProp):
foo = ReadOnlyProperty()
bar = IntProperty()
baz = FloatProperty()


Cool. But I wanted more power for my properties than just converting to a number. So I started thinking about a metaclass to transform something like this:

class Craziness(CrazyAutoProp):
def transform_foo(self, value):
# Insert all kinds of craziness here

into something like:


class FooDescriptor(object):
def __get__(self, instance, klass):
return instance._foo
def __set__(self, instance, value):
value = self.transform(instance, value)
instance._foo = value
def transform(self, value):
# Insert all kinds of craziness here

transform = staticmethod(transform)

class Craziness(object):
foo = FooDescriptor()


That was the point where the benefits seemed to move from writing legible code to writing less code. And also when I started wondering if the first example is even legible. Or if any of the metaclass code I've written for work in the past month is going to be comprehensible to anyone other than me. Bad Ryan! No more metaclasses for you.

(Note: As soon as I posted this I started reading the "What's New in Python 2.4" to see if I could learn about any other dark magic. Oh boy. At least I won't be able to use any of that at work)

No comments: