That's pretty neat, but returning the undo operation puts the responsibility of actually keeping track of undo operations on the caller side. I think it'd be better having each function push it's corresponding undo operation onto some global undo stack, thereby ensuring every operation gets recorded, without the caller having to do any work (or even know about the undo functionality).
But of course, you don't really need closures for that. For example, Cocoa does it this way:
- (void)deleteLineAtRow:(NSUInteger)row {
NSString *deletedLine = [self lineAtRow:row];
[[self.undoManager prepareWithInvocationTarget:self] insertLine:deletedLine atRow:row];
// do actual deletion
}
- (void)insertLine:(NSString *)line atRow:(NSUInteger)row {
[[self.undoManager prepareWithInvocationTarget:self] deleteLineAtRow:row];
// do actual insertion
}
That -prepareWithInvocation: stuff tells the undoManager to store the next message sent to it, along with it's parameters, on an internal stack. This is of course depends on Objective-C's dynamic nature and there's a whole lot of complexity hidden inside the undo manager object.
But mixing this undo manager concept with closures should be pretty straightforward, resulting in something like this (note that this is a hypothetical example; Cocoa does not currently implement this functionality):
- (void)deleteLineAtRow:(NSUInteger)row {
NSString *deletedLine = [self lineAtRow:row];
[self.undoManager registerUndoWithBlock:^{
[self insertLine:deletedLine atRow:row];
}];
// do actual deletion
}
- (void)insertLine:(NSString *)line atRow:(NSUInteger)row {
[self.undoManager registerUndoWithBlock:^{
[self deleteLineAtRow:row];
}];
// do actual insertion
}