On Wed, 18 Nov 2009 17:14:27 -0800, Steve Howell wrote: > In my rewritten code, here is the smell: > > dispatches = { > 'dict': _dict, > 'list': _list, > 'attr': _attr, > 'key': _key, > 'as': _as, > 'call': _call, > 'recurse': _recurse, > } > if kind in dispatches: > return dispatches[kind](ast) > else: > raise Exception('unknown kind!') > > > There is nothing wrong with the code taken out of context, but one of > the first things that lexical duplication should alert you to is the > fact that you are creating code that is brittle to extension.
Really? It is very simple to extend it by adding another key:item to the dict. > In my > example, the reference to _dict is 36 lines of code away from its > implementation, which forces indirection on the reader. It gets worse -- the reference to the in operator is in a completely different module to the implementation of the in operator, which may be in a completely different language! (C in this case.) I'm being sarcastic, of course, but I do have a serious point. I'm not impressed by complaints that the definition of the function is oh-so-very- far-away from where you use it. Well duh, that's one of the reasons we have functions, so they can be used anywhere, not just where they're defined. If a function *only* makes sense immediately where you use it, then the level of coupling is too great and you should either reduce the coupling or bite the bullet and live with all the hassles of inline code. (Code duplication, difficulty in testing, etc.) Of course it would be convenient if, having noticed the reference to (say) function _recurse, you could see its definition without needing to do more than just glance up a line or two. But you should rarely need to care about the implementation -- that's another point of functions. You should be able to treat _recurse as a black box, just as you use the built-in function len as a black box without needing to see its implementation every time you use it. -- Steven -- http://mail.python.org/mailman/listinfo/python-list