I wanted to figure out how to construct method names on the fly and invoke them. That way, I could have
dbChangeScript0
,dbChangeScript1
, and so forth, and then invoke them in a while loop that ran until the application didn't have a method with the relevant name. I wanted JavaScript's eval
function in Objective C. I didn't see how to do it, though.Today, I discovered
NSSelectorFromString
, a function that transforms a string into a selector (essentially, a function pointer). I used it to implement Plan A as follows:
- (void) installChangeScripts {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
int versionNum = [self dbVersionNumber];
SEL curSelector = NSSelectorFromString([NSString stringWithFormat:@"dbChangeScript%d",versionNum + 1]);
while ([self respondsToSelector:curSelector]) {
[self performSelector:curSelector];
[self updateDbVersion:versionNum +1];
versionNum = [self dbVersionNumber];
curSelector = NSSelectorFromString([NSString stringWithFormat:@"dbChangeScript%d",versionNum+1]);
}
[pool release];
}
Is this a better version? I've lost the self-documenting method names such as
makeVersionTable
, but I've removed an in-memory array and a #define that I had to remember to update when I updated the array. In other words, I've increased the code's maintainability. (The code looks shorter, but only because I also factored out the version update into a new method.) Overall, I consider this a win.The Ruby on Rails community has a mantra: convention over configuration. In Rails, you can get a full website up and running just by following a few naming conventions — ones you probably would have used anyway. A class of name X will translate to a database table named Y and so on. Compare that to Spring, a powerful Java framework that requires constant work in the XML-based configuration files.
In essence, I voted for the convention side of the fence in this code. By following a consistent naming scheme, I can write a small method that will do all the work. All I have to do is add a new method with a predictable name. Compare that to an array that I had to remember to configure properly.
No comments:
Post a Comment