Beautiful Code: Leading Programmers Explain How They Think by Andy Oram, Greg Wilson The unconfirmed error reports are from readers. They have not yet been approved or disproved by the author or editor and represent solely the opinion of the reader. Here's a key to the markup: [page-number]: serious technical mistake {page-number}: minor technical mistake : important language/formatting problem (page-number): language change or minor formatting problem ?page-number?: reader question or request for clarification This page was updated February 19, 2008. (1) Top Down Operator Precedence > Symbol Table > 9.2. Symbol Table; In the online-version in the chapter Top Down Operator Precedence > Symbol Table > 9.2. Symbol Table the variable "z" appears nowhere except in the return statement. This is probably a typo and should be "s". var symbol = function (id, bp) { var s = symbol_table[id]; ... return z; }; {69} line 19; In the method "isHexDigit" the line: case '@' : return true; should read : case '@' : return false; [70-71] Example 5-9; I don't program in Java very much, but wonder whether these problems are real: 1) As I read it, loadFlags will throw a RuntimeException if a problem occurs reading the data. If so, since the calls to it in the static block are not within a try/catch block, how will the code ever try to load the flags using the context class loader if the verifier's class loader fails? 2) If loadFlags does successfully find characters.dat, but what it finds does not have 65536 bytes in it, the flags array will be non-null but also not correctly initialized. 3) If characters.dat does not exist anywhere, flags will remain null, causing exceptions when it is indexed later in the code. The presence of the finally clause in loadFlags also confuses me: wouldn't the stream be closed automatically when in is garbage collected? If so, at most this prevents a subsequent error if too many file descriptors are open. Not that explicitly closing descriptors is a bad thing, but does Java guarantee that raw (declared in a scope that had already been left) would not have already been garbage- collected and closed prior to reaching the finally clause, or that if raw were closed it would continue to be safe to operate on in which wraps raw? Whether everything happens to work or not, it certainly is not clear that the code is correct. {294} 1st example, line 9; The "for" statement, when entered interactively, needs to be followed by an empty line; otherwise, the next entered line produces an error. So, as written, the example will not run interactively. But run from a file, it works OK. And we were just encouraged to run it interactively, so for a non-python devotee, this is an in-your-face issue. [300] 3rd paragraph from bottom; Detecting change during iteration, while accurately documented, documents a HACK -- and this is supposed to be beautiful code! If the body of the loop leaves the count unchanged (drops the current element, and adds a new one, for example), then no exception is thrown, but the iteration can be messed up. For example, this script ## demo HACK that iteration does not detect modification if inuse count remains unchanged ... d = { 1: "jan", 2: "feb" } print "Before ..." print d print "Working ..." for k,v in d.iteritems(): print k, v del d[k] d[k+10] = v + "-jelly" print "After ..." print d produced this result on my machine Before ... {1: 'jan', 2: 'feb'} Working ... 1 jan 2 feb 11 jan-jelly 12 feb-jelly 21 jan-jelly-jelly 22 feb-jelly-jelly 31 jan-jelly-jelly-jelly After ... {32: 'feb-jelly-jelly-jelly', 41: 'jan-jelly-jelly-jelly-jelly'} running this version of python: Python 2.3.4