Python meta-magic
I ran into a Python recipe the other day, Generating get/set methods using closures which I found useful for creating data objects from XML. Python's ability to add properties to objects at runtime makes some people cringe, but it was handy for hacking out a utility.
def make_setter(attr, typencv):
def setter(obj, val):
obj.__dict__[attr] = typencv(val)
return setter
make_setter is a function that returns a function that sets an attribute with the same name as attr to the value of the second argument, after applying typecnv. Then I defined a SGMLParser subclass where handle_data is overridden to call self.text_handler. In this example, start_mean sets the handler for the <mean> element to convert to an int:
def start_mean(self,attrs):
self.text_handler = make_setter("mean",int)
def handle_data(self, text):
# called for each block of plain text, i.e. outside of any tag and
# not containing any character or entity references
# Store the original text verbatim.
self.pieces.append(text)
if self.text_handler:
self.text_handler(self,text)
unknown_starttag provides a default text_handler if an overridden tag hasn't already done it:
def unknown_starttag(self, tag, attrs):
if not self.text_handler:
self.text_handler = make_setter(tag,str)
Comments
You do the same in Scheme but you just have to do the work at macro-expansion time. It is a bit less pleasant than programming at run-time but not too hard. I once wrote a macro-expansion time HTML tag stripper (it had to run at macro-expansion to interact with PLT's parser tools). Some day I may even document it and release it!
Noel Welsh at
comments are now closed on this post